[英]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.