簡體   English   中英

泛型的復雜繼承

[英]Complex inheritance with generics

假設我有一組類/接口:

class ObjectData { }
class UnitData : ObjectData { }
class Component1Data : UnitData { }
class Component2Data : UnitData { }

interface IObject { }
interface IUnit : IObject { }
interface IComponent1 : IUnit { }
interface IComponent2 : IUnit { }

abstract class Object<D, O, I>
    where D : ObjectData
    where O : Object<D, O, I>, I, new()
    where I : IObject
{ }

這里的主要關注點是Object類,它是某些層次結構中的基礎通用類。 類型參數“ O”是一種指定從Object派生的實際類的類型的方法。 因此,可以聲明和編譯類似這樣的內容而不會出現問題:

class Unit : Object<UnitData, Unit, IUnit>, IUnit { }

但是我要做的是定義另一個從Object派生的通用“第二級”類,該類也應充當幾個類似的“第三級”實體的基類。 它必須是非抽象的,因為它也是某種實體。 所以我需要定義這樣的東西:

class Unit<D, I> : Object<D, Unit<D, I>, I>, IUnit
    where D : UnitData
    where I : IUnit
{ }

class Component1 : Unit<Component1Data, IComponent1>, IComponent1 { }
class Component2 : Unit<Component2Data, IComponent2>, IComponent2 { }

並且它產生以下編譯錯誤:

error CS0311: The type 'Unit<D, I>' cannot be used as type parameter 'O' in the generic type or method 'Object<D, O, I>'. There is no implicit reference conversion from 'Unit<D, I>' to 'I'.

問題是為什么? 在我看來,如果Unit<D, I>實現IUnit ,並且將參數“ I”指定為where I : IUnit ,那么一切都應該很好。 我就是這樣看的。 我沒看到什么?

就像其他人評論的那樣,您的泛型太復雜了。 至少在我看來,不需要I類型參數,因為您的Object將實現相應的接口。

因此,代碼可以像這樣簡化:

abstract class Object<D, O> : IObject
    where D : ObjectData
    where O : Object<D, O>
{
}

class Unit<D> : Object<D, Unit<D>>, IUnit
    where D : UnitData
{
}

如果沒有完全的了解,很難說O將如何在Object的層次結構內部使用。是否有可能丟棄O類型參數。

您已經提到了靜態工廠方法-絕對不是帶來這種復雜性的原因。 但是,當然,您對用例了解更多。

簡化問題;

interface IObject { }
interface IUnit : IObject { }
interface IFoo : IUnit { }

abstract class Object<O, I>
    where O : Object<O, I>, I, new()
    where I : IObject
{}

class Unit : Object<Unit, IUnit>, IUnit
{
}

這很高興並且可以編譯。 我在這里用IUnit替換了I 現在更改為更派生的內容:

class Unit : Object<Unit, IFoo>, IUnit

然后您得到錯誤:

在通用類型或方法“對象”中,類型“單元”不能用作類型參數“ O”。 沒有從“單位”到“ IFoo”的隱式引用轉換。

所以...... Unit ,從派生IUnit不能轉換為IFoo ,即使都實現IUnit ......因為Unit不從派生IFoo ......這是對對象的條件:

where O : Object<O, I>, I`

這要求您做不允許做的事情:

class Unit<I> : Object<Unit<I>, I>, I

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM