C# 带泛型的复杂继承

C# 带泛型的复杂继承,c#,generics,inheritance,C#,Generics,Inheritance,假设我有一组类/接口: class ObjectData { } class UnitData : ObjectData { } class Component1Data : UnitData { } class Component2Data : UnitData { } interface IObject { } interface IUnit : IObject { } interface IComponent1 : IUnit { } interface IComponent2 : IU

假设我有一组类/接口:

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派生的通用“第二级”类,它也应该作为两个类似“第三级”实体的基类。它必须是非抽象的,因为它也是某种实体。所以我需要这样定义:

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 { }
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
{
}
类单位:对象,IUnit
其中D:UnitData
我在哪里:IUnit
{ }
类Component1:Unit,IComponent1{}
类Component2:Unit,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'.
错误CS0311:类型“Unit”不能用作泛型类型或方法“Object”中的类型参数“O”。没有从“单位”到“I”的隐式引用转换。

问题是为什么?在我的设想中,如果
单元
正在实现
IUnit
,并且参数“I”被指定为
,其中I:IUnit
,那么一切都应该正常。我就是这么看的。我没有看到什么?

像其他人评论的那样,您的泛型太复杂了。 至少,在我看来,没有必要使用
I
type参数,因为您的
对象将实现相应的接口

因此,代码可以简化如下:

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 { }
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
{
}
抽象类对象:IOObject
其中D:ObjectData
其中O:Object
{
}
类单位:对象,IUnit
其中D:UnitData
{
}
如果不完全理解,
O
将如何在
对象的层次结构中使用,很难说是否有可能丢弃
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
{
}
您会得到错误:

类型“Unit”不能用作泛型中的类型参数“O” 类型或方法“对象”。没有隐式引用 从“单位”转换为“IFoo”

所以<源于
IUnit
的code>Unit
不能转换为
IFoo
,即使两者都实现了
IUnit
。。。因为
Unit
不是从
IFoo
派生出来的。。。这是对象的一个条件:

where O : Object<O, I>, I`
其中O:Object,I`
这要求你做一些你不被允许做的事情:

class Unit<I> : Object<Unit<I>, I>, I
类单位:对象,I

这一定是我见过的最复杂的泛型用法了……如何在
对象中使用
O
?请发布示例代码。例如:public static O Create(D data){return data!=null?new O{data=data}:null;}public D data{get;private set;}我想引用Eric Lippert(C#上的权威,因为我自己不是):“更具体地说,我要说的是,你滥用仿制药。事实上,你建立的类型关系过于复杂,以至于你无法分析自己,这证明你应该简化整个过程;如果你没有保持所有的类型关系,并且你写了这些东西,那么你的用户肯定也不能保持它的正确性。“也许Eric是对的,但是这回答了我的问题吗?”我问定义为在对象上实现IEquatable和IComparable。还有一个集合类嵌套在实现IEnumerable的对象中。是的,我知道这个层次结构太复杂了。我已经在标题中说明了这一点。我想了解的是错误的原因——在我看来,这并不合理。不过还是谢谢你的回答。也许我真的需要简化所有这些。老实说,我不能理解你文章的第二部分。顺便说一句,我看不出用接口替换实际的类对我有什么帮助。伙计们,你们想告诉我如何简化模型。但遗憾的是,这并不是我一开始问的问题。这是一种简化,导致了相同的错误(我在visual studio 2015上,措辞似乎有所不同)。基本上,我相信你的问题是编译器无法将
单位转换为I
,因为条件要求
单位
I
,上面用更简单的术语说明了这一点。但是为什么呢?单元正在实现IUnit,“I”(遵循上述约束)是IUnit或从IUnit派生的内容。不是吗?我猜是因为它不能做共变。如果你让我知道它会变得快乐<代码>类单位:对象,IUnit