我有两个班级:
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的值为null
。
为什么我使用这样的方法签名? 因为该方法将被调用,而我无法预测框架元素是什么,例如:
myVar.MyMethod<TextBox>(t=>t.Text) ;
或
myVar.MyMethod<Label>(t=>t.Content) ;
答案 0 :(得分:0)
如上所述here:
函数功能&LT; T,TResult&gt;,具有协变返回类型和逆变 参数类型。
这意味着T参数可以是一个&#34;较少的派生类&#34;。
因此,如果您执行以下操作,则可以使用:
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&lt; MyFrameworkElement,Object&gt;到一个Func&lt; MyTextBox,Object&gt;,因为第一个参数是逆变的(你可以指定&#34;较少的派生类型&#34;在这种情况下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可以有一个你可以在MyMethod2中访问的Text属性,但是使用f4你会传递一个没有该属性的MyFrameworkElement。
不幸的是,你要做的是第二种情况。