c#

时间:2018-06-16 21:58:21

标签: c# reflection delegates .net-core

在下面的代码中,Read方法应该使用一个函数并通过一些简单的规则运行它:

public static void Read(Delegate handler)
{
    var values = new List<object>();
    foreach (var param in handler.Method.GetParameters())
    {
        Console.WriteLine($"{param.Name} : {param.ParameterType}");
        if (param.ParameterType == typeof(string))
        {
            values.Add(param.Name);
        }
        else
        {
            values.Add(null);
        }
    }

    handler.DynamicInvoke(values);
}

这是一个简单的函数:

public static void MyFunc(string p1, string p2)
{
    Console.WriteLine("Actual function");
}

但是这段代码是编译错误:

public static void Main(string[] args)
{
    Read(MyFunc);
}

错误是:

Argument 1: cannot convert from 'method group' to 'Delegate'

我认为Delegate可用于表示函数类型。为什么编译器无法将我的函数类型转换为Delegate

1 个答案:

答案 0 :(得分:0)

您只需要创建一种委托类型,该委托具有相同的方法签名,该签名将传递给接受委托的方法。我不会为此使用基本委托类型,创建自己的委托类型。

MSDN - How to: Declare, Instantiate, and Use a Delegate (C# Programming Guide)

有关代表类型的信息,请参阅此帖子。

Stack Overflow - Delegate vs delegate

  

来自http://msdn.microsoft.com/en-us/library/system.delegate.aspx:     Delegate类是委托类型的基类。但是,只有系统和编译器可以从Delegate类或MulticastDelegate类显式派生。也不允许从委托类型派生新类型。 Delegate类不被视为委托类型;它是用于派生委托类型的类。大多数语言实现委托关键字,这些语言的编译器能够从MulticastDelegate类派生;因此,用户应使用该语言提供的委托关键字。

<强>更新

根据你的评论,我进一步研究了这一点。我相信您的问题是您需要在传递方法之前将其转换为某种形式的委托,例如Action,Func或匿名方法。我仍然认为只能制作一个直接从方法接受所有可能的输入和输出的通用方法。首先将需要转换为委托兼容变量,然后需要传递变量。希望这适用于您需要做的事情。

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        // Display the contents of any method.
        Action<string> prntAct = TestMethod;
        PrintDelegate(prntAct);

        Action<string, string> prntAct2 = TestMethod2;
        PrintDelegate(prntAct2);

        Console.ReadKey();
    }

    public static void TestMethod(string xyz)
    {
        Console.WriteLine("Some random work to do.");
    }

    public static void TestMethod2(string abc, string def)
    {
        Console.WriteLine("Some other random work to do.");
    }

    private static void PrintDelegate(Delegate del)
    {
        var values = new List<object>();
        foreach (var param in del.Method.GetParameters())
        {
            Console.WriteLine($"{param.Name} : {param.ParameterType}");
            if (param.ParameterType == typeof(string))
            {
                values.Add(param.Name);
            }
            else
            {
                values.Add(null);
            }
        }
    }
}