我看不到以下代码有什么问题,或者如何解决。 (也许我误解了泛型类型。)
# works great
struct0['val'] + struct1['val']
编译器抱怨无法在通用类型class X<I>
where I : ISomeInterface
{ }
class Y<T>
where T : X<ISomeInterface>
{ }
class Z<I>
where I : ISomeInterface
{
Y<X<I>> AData { get; } // What compiler does not like
Y<X<ISomeInterface>> BData { get; } // What compiler likes
}
中将X<I>
用作类型参数T
。
答案 0 :(得分:4)
interface ISomeInterface {}
class X<I>
where I : ISomeInterface
{ }
class Y<T, I>
where T : X<I>
where I : ISomeInterface
{ }
class Z<I>
where I : ISomeInterface
{
Y<X<I>, I> MyOtherData { get; set; }
Y<X<ISomeInterface>, ISomeInterface> MyData { get; set; }
}
请注意,我在类型I
的定义中添加了附加的通用参数Y
和约束。
您对Y
的初始定义过于严格。 C#使ISomeInterface
与实现ISomeInterface
的任何类型有所不同。
为什么会这样?
.NET编译器具有处理通用类型的特殊方式。对于每种泛型类型,编译器将基于泛型类型参数创建一个单独的类型,该类型将在运行时使用。例如,List<int>
和List<string>
将是完全不同的类型,都表现出List<_>
泛型类型定义的行为,但实际类型为int
或string
嵌入到编译器生成的具体类型中。
定义class Y<T> where T : X<ISomeInterface>
时,会将“ X
”的通用参数“密封”为ISomeInterface
。即使X<ISomeInterface>
本身是X<SomethingElse>
的实现,编译器也可以接受继承SomethingElse
但不继承ISomeInterface
的任何类型。这是因为片段where T : X<ISomeInterface>
导致ISomeInterface
被放入Y<T>
的类型定义中。这种行为是预期的,并且是将泛型编译为实际代码的副作用。由于相同的原因,无法执行以下操作:
List<object> x = new List<string>();
即使类型string
继承自object
。