C# 转换函数<;T、 对象>;to Func<;框架元素,对象>;

C# 转换函数<;T、 对象>;to Func<;框架元素,对象>;,c#,generics,C#,Generics,我有两门课: class Model { //... public Func<FrameworkElement , object> Property { get; set; } //... } 或 myVar.MyMethod(t=>t.Content); 如上所述: Func,具有协变返回类型和逆变返回类型 参数类型 这意味着T参数可以是“派生较少的类” 因此,如果您执行以下操作,它将起作用: public class MyFrameworkElement

我有两门课:

class Model
{
    //...
    public Func<FrameworkElement , object> Property { get; set; }
    //...
}

myVar.MyMethod(t=>t.Content);
如上所述:

Func,具有协变返回类型和逆变返回类型 参数类型

这意味着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;
       }
}
公共类MyFrameworkElement{}
公共类MyTextBox:MyFrameworkElement{}
班级计划
{    
公共静态对象MyMethod(MyFrameworkElement b)
{
返回新对象();
}
静态void Main(字符串[]参数)
{
Func f1=MyMethod;
Func f2=f1;
}
}
如您所见,您可以将Func分配给Func,因为第一个参数是反变的(在本例中,您可以将“派生类型较少”的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 b)
{
返回新对象();
}
静态void Main(字符串[]参数)
{ 
Func f3=MyMethod2;
//这不会编译,而使用cast也无法实现。

Func f4=f3;//作为Func;这里泛型的意义是什么,为什么不指定
FrameworkElement
作为参数类型而不是使用约束?我将从另一个类调用该方法:myVar.MyMethod(t=>t.Text)或myVar.MyMethod(t=>t.Content);我无法预测其他开发人员将使用什么作为FrameworkElement您是否可以将MyMethod更改为:MyMethod(类型类型,Func选择器)并使用多态性*编辑的注释,因为在我完成之前意外提交了它。如果您必须将其作为泛型,您可以始终尝试包装lambda,如:
Func SelectorWrapper=f=>selector((t)f) 
并改用它。
myVar.MyMethod<TextBox>(t=>t.Text) ; 
myVar.MyMethod<Label>(t=>t.Content) ;
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;
       }
}
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
    }
}