Func中的方差<>参数

时间:2013-11-23 23:36:41

标签: c# c#-4.0 generics lambda variance

我一直在尝试做类似

的事情
Func<string, bool> f
Func<object, bool> F = f;

并且编译器引发以下错误:

  

无法隐式将'System.Func<string,bool>'类型转换为'System.Func<object,bool>'

但是,我们显然可以object x = "123"

3 个答案:

答案 0 :(得分:5)

想象一下,如果你这样做了:

Func<string, bool> fStr = str => str.Length > 10;
Func<object, bool> fObj = fStr;

嗯,根据fObj的签名,您应该可以使用以下任何参数调用它:

fObj(7);

fStr显然无效。

答案 1 :(得分:4)

委托类型Func<in T, out TResult>在其第一个类型参数T中显然是 逆变 。可以接受任何对象的“func”也可以包含字符串,因此Func<object, X>“是”Func<string, X>,因此这是in类型{{1}中的逆转}。

你正试图走另一条路。只有当您碰巧知道运行时类型确实是T时,这才有效,并且您需要显式的强制语法来通知编译器您的知识。如果运行时类型不正确,则显式强制转换将失败。

有效示例:

Func<object, bool>

答案 2 :(得分:0)

来自MSDN

  

隐含转化:     不需要特殊语法,因为转换是类型安全的,不会丢失任何数据。示例包括从较小到较大的整数类型的转换,以及从派生类到基类的转换。

     

显式转换(强制转换):显式转换需要强制转换运算符。如果信息可能在转换中丢失,或者由于其他原因导致转换失败,则需要进行转换。典型示例包括将数值转换为精度较低或范围较小的类型,以及将基类实例转换为派生类。

你不能这样做,因为你会丢失信息。 如果你以另一种方式尝试,你可以这样做

 Func<object, bool> f = ....;
 Func<string, bool> F = f;

因为你不会丢失信息。

一个简单的例子是:

// This is ok. you can fit int in double
int some_int = 42;
double some_double = some_int;

// This is not ok. you might lose information
double some_double_2 = 42;
int some_int_2 = some_double_2;


// But you could do this, where the casts says: "Yep, I'm aware I might lose some
// information, but I'm an UBER programmer and want to do it anyways"
int some_int_3 = (int)some_double_2;

您可以投射或编写自己的默认转化。看看上面的MSDN链接:)