[英]The type X cannot be used as type parameter T in the generic type Y
I don't see what is wrong with the following code, or how I can fix it. 我看不到以下代码有什么问题,或者如何解决。 (Maybe I am misunderstanding generic types.)
(也许我误解了泛型类型。)
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
}
Compiler complains that it cannot use X<I>
as type parameter T
in the generic type Y<T>
. 编译器抱怨它不能使用
X<I>
作为泛型类型Y<T>
中的类型参数T
Here is a working solution 这是一个可行的解决方案
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; }
}
Notice the additional generic parameter I
and constraints I have added to the definition of type Y
. 请注意,
I
在类型Y
的定义中添加了其他通用参数I
和约束。
Your initial definition of Y
is too restrictive. 您最初对
Y
定义过于严格。 C# makes a difference between ISomeInterface
and any type implementing ISomeInterface
. C#使
ISomeInterface
与实现ISomeInterface
任何类型有所不同。
Why is it so ? 为什么会这样呢?
The .NET compiler has a special way of handing generic types. .NET编译器具有处理通用类型的特殊方式。 For each generic type the compiler will create a separate type based on the generic type arguments, which is instead used during runtime.
对于每种泛型类型,编译器将基于泛型类型参数创建一个单独的类型,该类型将在运行时使用。 For example
List<int>
and List<string>
will be completely different types, all exhibiting the behaviours defined by the List<_>
generic type, but with the actual type int
or string
baked into the concrete type generated by the compiler. 例如,
List<int>
和List<string>
将是完全不同的类型,它们都表现出List<_>
泛型类型定义的行为,但是实际类型为int
或string
,已编译为编译器生成的具体类型。
When you define class Y<T> where T : X<ISomeInterface>
you "seal" the generic parameter of X
to be ISomeInterface
. 当定义
class Y<T> where T : X<ISomeInterface>
你“密封”的通用参数X
是ISomeInterface
。 The compiler will accept any type inheriting X<ISomeInterface>
but not X<SomethingElse>
even if SomethingElse
is itself an implementation of ISomeInterface
. 即使
SomethingElse
本身是ISomeInterface
的实现,编译器也可以接受继承X<ISomeInterface>
任何类型,但不能接受X<SomethingElse>
任何类型。 This is because the fragment where T : X<ISomeInterface>
causes the ISomeInterface
to be "baked in" within the type definition of Y<T>
. 这是因为
where T : X<ISomeInterface>
的片段导致ISomeInterface
被“烘焙”到Y<T>
的类型定义中。 That behaviour is expected and is a side effect of how generics are compiled to actual code. 这种行为是预期的,并且是将泛型编译为实际代码的副作用。 For the same reason one cannot do the following:
出于相同的原因,不能执行以下操作:
List<object> x = new List<string>();
even though the type string
inherits from object
. 即使类型
string
从object
继承的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.