简体   繁体   English

类型X不能用作通用类型Y中的类型参数T

[英]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<_>泛型类型定义的行为,但是实际类型为intstring ,已编译为编译器生成的具体类型。

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>你“密封”的通用参数XISomeInterface 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 . 即使类型stringobject继承的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 类型“ T”不能用作通用类型或方法中的类型参数“ T” - The type 'T' cannot be used as type parameter 'T' in the generic type or method 类型&#39;&#39;不能在通用类型或方法中用作类型参数&#39;T&#39; - The type '' cannot be used as type parameter 'T' in the generic type or method 类型“ XXX”不能用作通用类型或方法中的类型参数“ T” - The type 'XXX' cannot be used as type parameter 'T' in the generic type or method 泛型:“相机”类型不能用作泛型类型中的类型参数“T” - Generics: The type 'Camera' cannot be used as type parameter 'T' in the generic type 通用方法-类型不能用作类型参数 - Generic method - Type cannot be used as Type Parameter 当类型已知时,类型&#39;T&#39;不能用作泛型类型或方法错误中的类型参数 - The type 'T' cannot be used as type parameter in the generic type or method error when type is known 该类型不能用作通用类型或方法中的类型参数 - The type cannot be used as type parameter in the generic type or method 类型“”不能用作泛型类型“ICrudAppService”中的类型参数“TEntityDto” - The type '' cannot be used as type parameter 'TEntityDto' in the generic type 'ICrudAppService' 该类型不能用作泛型类型或方法UserStore中的类型参数TRole - The type cannot be used as type parameter TRole in the generic type or method UserStore 该类型不能在泛型类型或方法'BaseController <T>'中用作类型参数'T'。没有隐含的参考 - The type cannot be used as type parameter 'T' in the generic type or method 'BaseController<T>'. There is no implicit reference
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM