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