转换为泛型方法不支持的基类型
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;
}
}
}
现在,当我创建 class 的实例并将其转换回 IGenericOrder<object>
var sorter = (IGenericOrder<object>) new GenericOrder<Foo>();
我得到异常:
InvalidCastException: The instance of type GenericOrder<Foo>
cannot be cast to IGenericOrder<object>
这似乎很清楚,因为接口 IGenericOrder
不是协变的。但是,如果我使接口协变 (interface IGenericOrder<out T>
),我会得到一个编译器错误:
Invalid variance: The type parameter 'T' must be contravariantly valid on IGenericOrder<T>.GetStatement(string)
. 'T' is covariant.
正如我从 here 中读到的那样,协方差只能在
时使用
[the generic type parameter] is used only as a method return type and is not used as a type of formal method parameters.
这是否意味着我不能将 co-/contravariance 用于自身具有 return 个通用实例的方法?
我正在使用 .Net 4.5
您正在使用 T
作为 Func
的第一个类型参数,因此唯一有效的模式是 contravariance 因为 T
表示函数参数的类型。你试图用你的演员实现的是不安全的:你说 "Here's a function which takes a Foo
as a parameter. Please treat this as a function which takes any object
as a parameter." 如果你有一个 Func<int, T>
,你可以使用协方差,因为一个函数 returns a Foo
也可以看作是 returns 和 object
.
的函数
要了解发生了什么,请查看 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);
}
}
我有一个接口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;
}
}
}
现在,当我创建 class 的实例并将其转换回 IGenericOrder<object>
var sorter = (IGenericOrder<object>) new GenericOrder<Foo>();
我得到异常:
InvalidCastException: The instance of type
GenericOrder<Foo>
cannot be cast toIGenericOrder<object>
这似乎很清楚,因为接口 IGenericOrder
不是协变的。但是,如果我使接口协变 (interface IGenericOrder<out T>
),我会得到一个编译器错误:
Invalid variance: The type parameter 'T' must be contravariantly valid on
IGenericOrder<T>.GetStatement(string)
. 'T' is covariant.
正如我从 here 中读到的那样,协方差只能在
时使用[the generic type parameter] is used only as a method return type and is not used as a type of formal method parameters.
这是否意味着我不能将 co-/contravariance 用于自身具有 return 个通用实例的方法?
我正在使用 .Net 4.5
您正在使用 T
作为 Func
的第一个类型参数,因此唯一有效的模式是 contravariance 因为 T
表示函数参数的类型。你试图用你的演员实现的是不安全的:你说 "Here's a function which takes a Foo
as a parameter. Please treat this as a function which takes any object
as a parameter." 如果你有一个 Func<int, T>
,你可以使用协方差,因为一个函数 returns a Foo
也可以看作是 returns 和 object
.
要了解发生了什么,请查看 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);
}
}