[英]cast to base-type not supported for generic method
我有一个接口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;
}
}
}
现在,当我创建该类的实例并将其转换回IGenericOrder<object>
var sorter = (IGenericOrder<object>) new GenericOrder<Foo>();
我得到例外:
InvalidCastException:
GenericOrder<Foo>
类型的实例无法强制转换为IGenericOrder<object>
这似乎很清楚,因为接口IGenericOrder
不是协变的。 但是,如果我使接口协变( interface IGenericOrder<out T>
),我得到一个编译器错误:
方差无效:类型参数“T”必须在
IGenericOrder<T>.GetStatement(string)
上IGenericOrder<T>.GetStatement(string)
有效。 'T'是协变的。
正如我从这里读到的那样,协方差只能用于
[泛型类型参数]仅用作方法返回类型,不用作形式方法参数的类型。
这是否意味着我不能对自己返回通用实例的方法使用共同/逆变?
我正在使用.Net 4.5
要了解发生了什么,请查看Func<T,TResult>
委托的定义:
public delegate TResult Func<in T, out TResult>(
T arg
)
如您所见,其第一个类型参数T
是in
参数。 因此,您不能将out
参数用作Func
的第一个类型参数。 第二个类型参数TResult
已经out
,因此使用T
作为TResult
可以工作:
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);
}
}
您使用T
作为Func
的第一个类型参数,因此唯一有效的模式是逆变量,因为T
表示函数参数的类型。 你试图通过你的演员实现的是不安全的:你说“这是一个以Foo
为参数的函数。请把它当作一个以任何object
作为参数的函数。” 如果您有一个Func<int, T>
,则可以使用协方差,因为返回Foo
的函数也可以被视为返回object
的函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.