简体   繁体   English

什么是C#中最通用的函数类型

[英]What is the most generic function type in c#

In the following piece of code, the Read method is supposed to take a function and run it by some simple rules: 在下面的代码中, 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);
}

And here is a simple function to call: 这是一个简单的函数:

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

But this code is compile error: 但是这段代码是编译错误:

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

And the error is: 错误是:

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

I thought Delegate can be used to represent a function type. 我认为Delegate可用于表示函数类型。 Why compiler cannot convert my function type to a Delegate ? 为什么编译器无法将我的函数类型转换为Delegate

You just need to create a type of delegate with the same signature of the method that will be passed into the method accepting the delegate. 您只需要创建一种具有与方法相同签名的委托类型,该签名将传递到接受委托的方法中。 I wouldn't use the base Delegate type for this, create your own delegate type. 我不会为此使用基本的委托类型,而是创建自己的委托类型。

MSDN - How to: Declare, Instantiate, and Use a Delegate (C# Programming Guide) MSDN-如何:声明,实例化和使用委托(C#编程指南)


See this post for information about the Delegate type. 有关此代理类型的信息,请参见此文章。

Stack Overflow - Delegate vs delegate 堆栈溢出-委托与委托

From http://msdn.microsoft.com/en-us/library/system.delegate.aspx : The Delegate class is the base class for delegate types. http://msdn.microsoft.com/zh-cn/library/system.delegate.aspx:Delegate类是委托类型的基类。 However, only the system and compilers can derive explicitly from the Delegate class or from the MulticastDelegate class. 但是,只有系统和编译器才能从Delegate类或MulticastDelegate类显式派生。 It is also not permissible to derive a new type from a delegate type. 也不允许从委托类型派生新类型。 The Delegate class is not considered a delegate type; Delegate类不被视为委托类型。 it is a class used to derive delegate types.Most languages implement a delegate keyword, and compilers for those languages are able to derive from the MulticastDelegate class; 大多数语言都实现了委托关键字,并且这些语言的编译器都可以从MulticastDelegate类派生。 therefore, users should use the delegate keyword provided by the language. 因此,用户应使用该语言提供的委托关键字。


Update 更新资料

As per your comment I looked into this a bit further. 根据您的评论,我对此进行了进一步研究。 I believe your issue is that you need to convert the method to some form of delegate before passing it such as an Action, Func or anonymous method. 我相信您的问题是,在传递该方法之前,您需要将其转换为某种形式的委托,例如Action,Func或匿名方法。 I still don't think it is possible to just make a generic method which just accepts all possible inputs and outputs directly from a method. 我仍然认为不可能仅创建一个通用方法来直接接受该方法的所有可能的输入和输出。 It will need to first be converted into a delegate compatible variable, then the variable will need to be passed. 首先需要将其转换为委托兼容变量,然后再传递该变量。 Hopefully, this works for what you need to do. 希望这可以满足您的需要。

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);
            }
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM