C# 仿制药铸造 接口基{…} 子类:基{…} 类OtherBase,其中T:Base{…} 类OtherSub:OtherBase,其中T:Base{…} //…在某个班级 void Call(),其中T:OtherBase{} //... Call()//编译失败。。。

C# 仿制药铸造 接口基{…} 子类:基{…} 类OtherBase,其中T:Base{…} 类OtherSub:OtherBase,其中T:Base{…} //…在某个班级 void Call(),其中T:OtherBase{} //... Call()//编译失败。。。,c#,generics,C#,Generics,似乎在使用泛型时,编译器不会在 泛型类型(OtherBase/OtherSub)。为什么会发生这种情况 更新: 还请解释上述内容与以下内容之间的区别(哪些有效) void Call(),其中T:Base{} //... Call(); 禁止这种行为(称为“通用差异”)是必要的,因为否则将编译以下代码: void Call<T>() where T : Base { } //... Call<Sub>(); 这样称呼它: static void Call<U, T&

似乎在使用泛型时,编译器不会在 泛型类型(OtherBase/OtherSub)。为什么会发生这种情况

更新: 还请解释上述内容与以下内容之间的区别(哪些有效)

void Call(),其中T:Base{}
//...
Call();
禁止这种行为(称为“通用差异”)是必要的,因为否则将编译以下代码:

void Call<T>() where T : Base { }
//...
Call<Sub>();
这样称呼它:

static void Call<U, T>(T x) where U : Base where T : OtherBase<U> { }
Call(new OtherSub<Sub());

Call(new OtherSub您的问题与一个称为方差/协方差的概念相关联。事实上,如果
a
继承自
B
Class
不是

请参见此示例:

Class
公开一个公共方法
foo(T参数)

如果
Class
Class
,那么将
Class
引用为
Class
并调用
foo(B参数)
(使用
B
实例)的方法将调用
foo(a参数)
,而
B
不是
a

实际上,只有当
T
仅在
Class
中用作返回值时,
Class
才能从
Class
继承


这是通过泛型接口的out关键字在.NET 4中强制执行的。
Class
因此可以实现
icclass

Konrad对如何修复代码提出了很好的建议。如果您想使用C#4的方差,您可以这样做:

static void Call<U, T>(T x) where U : Base where T : OtherBase<U> { }
Call(new OtherSub<Sub());
接口,其中T:Base{}
类OtherBase:iot,其中T:Base{}
类OtherSub:OtherBase,其中T:Base{}
静态void调用(),其中T:iot{}

Call()
就可以了。

这对于给定的示例来说很有意义,但是对于方法调用来说仍然没有意义。您能否解释一下您的示例与“void Call(),其中t:Base{}”,“Call()”之间的区别求求你了?@james True,我的错误。修正了。你的扩展问题与通用方差完全无关,所以没有理由不起作用。
interface IOtherBase<out T> where T : Base { }

class OtherBase<T> : IOtherBase<T> where T : Base { }
class OtherSub<T> : OtherBase<T> where T : Base { }

static void Call<T>() where T : IOtherBase<Base> { }