转换函数<;T、 对象>;到Func<;FrameworkElement,对象>;
本文关键字:对象 gt lt Func FrameworkElement 函数 转换 | 更新日期: 2023-09-27 18:26:27
我有两个类:
class Model
{
//...
public Func<FrameworkElement , object> Property { get; set; }
//...
}
和
class Other
{
public void MyMethod<T>(Type type, Func<T, object> selector) where T : FrameworkElement
{
this.MyList.Add(new Model() { Property = selector });
}
}
我有一个错误:Impossible to convert Func<T,object> to Func<FrameworkElement,object>
当我尝试时:
var tmp = selector as Func<FrameworkElement, object>
tmp的值是CCD_ 2。
为什么我要使用这样的方法签名?因为该方法将被调用,而我无法预测框架元素是什么,例如:
myVar.MyMethod<TextBox>(t=>t.Text) ;
或
myVar.MyMethod<Label>(t=>t.Content) ;
如上所述:
Func<TTResult>,具有协变返回类型和逆变参数类型。
这意味着T参数可以是一个"派生程度较低的类"。
因此,如果你做以下操作,它是有效的:
public class MyFrameworkElement { }
public class MyTextBox : MyFrameworkElement { }
class Program
{
public static Object MyMethod(MyFrameworkElement b)
{
return new Object();
}
static void Main(string[] args)
{
Func<MyFrameworkElement, Object> f1 = MyMethod;
Func<MyTextBox, Object> f2 = f1;
}
}
正如您所看到的,您可以指定一个Func<MyFrameworkElement,Object>到Func<MyTextBox,Object>,因为第一个参数是反变量的(在这种情况下,您可以将"派生较少的类型"MyFrameworkElement分配给MyTextBox)。
就像我说的,类型参数是逆变的,而不是协变的,所以它不能反过来工作!
像这样:
class Program
{
public static Object MyMethod2(MyTextBox b)
{
return new Object();
}
static void Main(string[] args)
{
Func<MyTextBox, Object> f3 = MyMethod2;
//This does not compile, and with cast you cannot make this work either.
Func<MyFrameworkElement, Object> f4 = f3; // as Func<MyFrameworkElement, Object>; <- does not help
}
}
这是有道理的,因为MyMethod2有一个MyTextBox参数,f4将指向一个MyFrameworkElement。MyTextBox可以有一个Text属性,您可以在MyMethod2中访问该属性,但使用f4,您将传递一个没有该属性的MyFrameworkElement。
不幸的是,你想做的是第二种情况。