C# 泛型方法不支持转换为基类型
我有一个接口C# 泛型方法不支持转换为基类型,c#,generics,covariance,C#,Generics,Covariance,我有一个接口IGenericOrder,如下所示: using System; using System.Linq.Expressions; namespace MyNamespace { interface IGenericOrder<T> where T : new() { Func<T, int> GetStatement(string name); } public class GenericOrder<
IGenericOrder
,如下所示:
using System;
using System.Linq.Expressions;
namespace MyNamespace
{
interface IGenericOrder<T> where T : new()
{
Func<T, int> GetStatement(string name);
}
public class GenericOrder<T> : IGenericOrder<T> where T : new()
{
public Func<T, int> GetStatement(string name)
{
return (T) => 4;
}
}
}
使用系统;
使用System.Linq.Expressions;
名称空间MyNamespace
{
接口IGenericOrder,其中T:new()
{
Func GetStatement(字符串名称);
}
公共类GenericOrder:IGenericOrder,其中T:new()
{
public Func GetStatement(字符串名称)
{
返回值(T)=>4;
}
}
}
现在,当我创建该类的实例并将其转换回IGenericOrder
var-sorter=(IGenericOrder)新的GenericOrder();
我得到一个例外:
InvalidCastException:typeGenericOrder
的实例无法强制转换为IGenericOrder
这似乎很清楚,因为接口IGenericOrder
不是协变的。但是,如果我使接口协变(接口IGenericOrder
),我会得到一个编译器错误:
无效差异:类型参数“T”必须在IGenericOrder.GetStatement(string)
上反向有效T’是协变的
正如我从协方差中读到的,只有在
[泛型类型参数]仅用作方法返回类型,不用作形式方法参数的类型
这是否意味着我不能对自身返回泛型实例的方法使用协方差/逆变
我使用.Net 4.5您使用
T
作为Func
的第一个类型参数,因此唯一有效的模式是逆变模式,因为T
表示函数参数的类型。您试图通过强制转换实现的是不安全的:您说的是“这是一个函数,它将Foo
作为参数。请将此函数视为一个函数,它将任何对象
作为参数。”如果您使用的是Func
,则可以使用协方差,因为返回Foo
的函数也可以看作是返回对象的函数
要了解发生了什么,请查看委托的定义:
public delegate TResult Func<in T, out TResult>(
T arg
)
是的。我的意思是,你已经掌握了你需要的所有信息,并且你正确地解释了它。这甚至是有道理的。你还想找什么?嗯,这就是错误告诉我的,但我不完全理解这件事的激烈程度。从您的角度来看,什么才是有意义的呢?试想一下——您返回的函数的参数类型为
T
。如果允许您将接口强制转换为IGenericOrder
,它将返回一个函数,该函数采用object
类型的参数。并非所有的T
s都是object
s-您破坏了类型安全。另一方面,您可以使用T
contra variant-将子类而不是父类作为参数传递是有效的。。。以某种方式谢谢,我明白了,有了Func
的签名,这一点就显而易见了。谢谢你指出这一点
public delegate TResult Func<in T, out TResult>(
T arg
)
interface IGenericOrder<out T> where T : new() {
Func<int,T> GetStatement(string name);
}
public class GenericOrder<T> : IGenericOrder<T> where T : new() {
public Func<int,T> GetStatement(string name) {
return (x) => default(T);
}
}