C# Can';t将匿名委托分配给签名委托

C# Can';t将匿名委托分配给签名委托,c#,delegates,anonymous-delegates,C#,Delegates,Anonymous Delegates,我正在寻找一种方法,将列表中的不同委托分配给MethodInfo,而不必事先了解返回类型的信息。下面是我正在使用的代码。这些评论提供了关于正在发生的事情的更多信息。这是一段很长的代码,但我已经尽可能地减少了它 主要片段 private const string methodName = "Execute"; public static void Main() { ExampleClass1 e1 = new ExampleClass1(); Ex

我正在寻找一种方法,将列表中的不同委托分配给
MethodInfo
,而不必事先了解返回类型的信息。下面是我正在使用的代码。这些评论提供了关于正在发生的事情的更多信息。这是一段很长的代码,但我已经尽可能地减少了它

主要片段

private const string methodName = "Execute";

    public static void Main()
    {
        ExampleClass1 e1 = new ExampleClass1();
        ExampleClass2 e2 = new ExampleClass2();
        ExampleClass3 e3 = new ExampleClass3();

        /* Code below Simulates:  "e3.GetString = e2.Execute;" */
        var method = e2.GetType().GetMethod(methodName);

        for (int i = 0; i < e3.DelegateList.Count; i++)
        {
            // First check the type of e2 return
            Type methodType = method.ReturnType;

            // Check that its the same return type as delegate
            if (methodType != e3.DelegateList[i].ReturnType)
                continue;

            // Assign delegate to method
            var returnType = e3.DelegateList[i].DelegateType;
            e3.DelegateList[i].Delegate = Delegate.CreateDelegate(returnType, e2, method);

            /* Code below only for debugging */
            Console.WriteLine("The delegate in the list: " + e3.DelegateList[i].Delegate);// Returns Type of StringHandler
            Console.WriteLine("The delegate in the object: " + e3.GetString);// Returns null
            e3.GetString = e3.DelegateList[i].Delegate;// This throws Error Cannot convert Delegate to StringHandler
        }

        /* Code above Simulates:  "e3.GetString = e2.Execute;" */

        e2.GetNumber = e1.Execute;

        e3.Execute();// Throws Null References Exception on

        // Read the key
        Console.ReadKey();
    }
private const string methodName=“Execute”;
公共静态void Main()
{
ExampleClass e1=新的ExampleClass();
ExampleClass2 e2=新ExampleClass2();
ExampleClass3 e3=新ExampleClass3();
/*下面的代码模拟:“e3.GetString=e2.Execute*/
var method=e2.GetType().GetMethod(methodName);
对于(int i=0;i
支持类/代码

如果您需要有关支持类的更多信息,请参阅下面的代码。此外,这是一个自包含的程序,应该可以按原样运行

 public class ExampleClass3
{
    public delegate string StringHandler();

    public delegate int IntHandler();

    public StringHandler GetString { get; set; }
    public IntHandler GetInt { get; set; }

    public List<DelegateInfo<Type, Type, Delegate>> DelegateList { get; set; }

    public ExampleClass3()
    {
        DelegateList = new List<DelegateInfo<Type, Type, Delegate>>();
        DelegateList.Add(new DelegateInfo<Type, Type, Delegate>(typeof(StringHandler), typeof(string), GetString));
        DelegateList.Add(new DelegateInfo<Type, Type, Delegate>(typeof(IntHandler), typeof(int), GetInt));
    }

    public object Execute()
    {
        Console.WriteLine(GetString());

        return null;
    }
}

public class ExampleClass2
{
    public delegate int NumberHandler();

    public NumberHandler GetNumber { get; set; }

    public string Execute() => $"Your Number Is {GetNumber()}";
}

public class ExampleClass1
{
    public int number = 5;

    public int Execute() => number;
}

public class DelegateInfo<T1, T2, T3>
{
    public DelegateInfo(T1 delegateType, T2 returnType, T3 @delegate)
    {
        DelegateType = delegateType;
        ReturnType = returnType;
        Delegate = @delegate;
    }

    public T1 DelegateType { get; set; }
    public T2 ReturnType { get; set; }
    public T3 Delegate { get; set; }
}
public类示例class3
{
公共委托字符串StringHandler();
公共委托int IntHandler();
公共StringHandler GetString{get;set;}
公共IntHandler GetInt{get;set;}
公共列表委托列表{get;set;}
公共示例Class3()
{
DelegateList=新列表();
添加(新的DelegateInfo(typeof(StringHandler)、typeof(string)、GetString));
添加(新的DelegateInfo(typeof(IntHandler)、typeof(int)、GetInt));
}
公共对象执行()
{
WriteLine(GetString());
返回null;
}
}
公共类示例Class2
{
公共委托int NumberHandler();
public NumberHandler GetNumber{get;set;}
公共字符串Execute()=>$“您的号码是{GetNumber()}”;
}
公共课范例1
{
公共整数=5;
public int Execute()=>number;
}
公共类委派信息
{
公共委托信息(T1委托类型、T2返回类型、T3@delegate)
{
DelegateType=DelegateType;
ReturnType=ReturnType;
Delegate=@Delegate;
}
公共T1委托类型{get;set;}
公共T2返回类型{get;set;}
公共T3委托{get;set;}
}

缺少一个演员阵容:

e3.GetString = (ExampleClass3.StringHandler)e3.DelegateList[i].Delegate;

我对您的代码进行了一些简化,以演示如何进行此操作。首先,不要创建特殊的DelegateInfo类-尽可能使用标准的.NET反射库。他们在这方面做得很好,但确实需要一段时间来学习

代码如下:

    private const string methodName = "Execute";

    public static void Main()
    {
        ExampleClass1 e1 = new ExampleClass1();
        ExampleClass2 e2 = new ExampleClass2();
        ExampleClass3 e3 = new ExampleClass3();

        /* Code below Simulates:  "e3.GetString = e2.Execute;" */
        var method = e2.GetType().GetMethod(methodName);            
        Type methodType = method.ReturnType;

        // Create a Func<T> that will invoke the target method            
        var funcType = typeof(Func<>).MakeGenericType(methodType);
        var del = Delegate.CreateDelegate(funcType, e2, method);

        var properties = e3.GetType().GetProperties();
        for (int i = 0; i < properties.Length; i++)
        {              
            if (properties[i].PropertyType.IsAssignableFrom(funcType)) {
                properties[i].SetValue(e3, del );
            }
        }

        /* Code above Simulates:  "e3.GetString = e2.Execute;" */

        e2.GetNumber = e1.Execute;

        e3.Execute();

        // Read the key
        Console.ReadKey();
    }
    public class ExampleClass3
    {         
        public Func<String> GetString { get; set; }
        public Func<int> GetInt { get; set; }

        public ExampleClass3()
        { }

        public object Execute()
        {
            Console.WriteLine(GetString());
            return null;
        }
    }

    public class ExampleClass2
    {
        public Func<int> GetNumber { get; set; }

        public string Execute() => $"Your Number Is {GetNumber()}";
    }

    public class ExampleClass1
    {
        public int number = 5;

        public int Execute() => number;
    }
private const string methodName=“Execute”;
公共静态void Main()
{
ExampleClass e1=新的ExampleClass();
ExampleClass2 e2=新ExampleClass2();
ExampleClass3 e3=新ExampleClass3();
/*下面的代码模拟:“e3.GetString=e2.Execute*/
var method=e2.GetType().GetMethod(methodName);
类型methodType=method.ReturnType;
//创建将调用目标方法的Func
var funcType=typeof(Func).MakeGenericType(methodType);
var del=Delegate.CreateDelegate(funcType,e2,方法);
var properties=e3.GetType().GetProperties();
for(int i=0;i$“您的号码是{GetNumber()}”;
}
公共课范例1
{
公共整数=5;
public int Execute()=>number;
}
首先,请注意我是如何摆脱自定义委托定义而使用Func的。这将被证明更容易以通用方式使用。请注意ExampleClass3现在是如何定义的:

    public class ExampleClass3
    {         
        public Func<String> GetString { get; set; }
        public Func<int> GetInt { get; set; }

        public ExampleClass3()
        { }

        public object Execute()
        {
            Console.WriteLine(GetString());
            return null;
        }
    }
public类示例class3
{         
public Func GetString{get;set;}
公共函数GetInt{get;set;}
公共示例Class3()
{ }
公共对象执行()
{
WriteLine(GetString());
返回null;
}
}
我可以利用所有这些函数都是Func类型的事实来开发一个通用的解决方案,为它们赋值。根据目标方法的返回类型,我可以
    var funcType = typeof(Func<>).MakeGenericType(methodType);
    var del = Delegate.CreateDelegate(funcType, e2, method);
        var properties = e3.GetType().GetProperties();
        for (int i = 0; i < properties.Length; i++)
        {              
            if (properties[i].PropertyType.IsAssignableFrom(funcType)) {
                properties[i].SetValue(e3, del );
            }
        }