C# 如何为泛型方法创建委托?

C# 如何为泛型方法创建委托?,c#,.net,generics,delegates,C#,.net,Generics,Delegates,我有一个简单的课程: class Test { public static int Test<T>(T arg) { return 1; } } 我想得到一个代表这个方法的Delegate类型的对象。是否可以创建这样的委托?如果我能将一个具有任意数量参数和泛型参数的方法转换为委托,那就更好了。它似乎是您正在寻找的 您可以使用以下命令来获取委托对象 Func<int> func = () => Test<Foo>(

我有一个简单的课程:

class Test
{
    public static int Test<T>(T arg)
    {
        return 1;
    }
}
我想得到一个代表这个方法的Delegate类型的对象。是否可以创建这样的委托?如果我能将一个具有任意数量参数和泛型参数的方法转换为委托,那就更好了。

它似乎是您正在寻找的

您可以使用以下命令来获取委托对象

Func<int> func = () => Test<Foo>(bar);

这取决于您是否需要返回值和这样的寄存器

ImportMethod("Name", () => Test<Foo>(bar))

您不想在这里使用委托。您需要一个实例:

void ImportMethod(string name, MethodInfo method)
你可以这样称呼它:

void ImportMethod("Test", typeof(Test).GetMethod("Test", ...Static));

如果使用泛型编写方法以保持类型安全,则需要为每个具有不同数量输入参数的方法编写两个方法,一个用于void方法操作,另一个用于返回值Func的方法。 我加入了一个helper类,因为它减少了每个方法导入必须传递的泛型参数的数量。在调用该方法时,它也有助于intellisense

    public class Foo
    {
        public void Bar()
        {
        }

        public void Bar(string input)
        {
        }

        public bool BarReturn()
        {
            return false;
        }
    }

    public class ImportHelper<TClass>
    {
        public void Import(string name, Expression<Action<TClass>> methodExpression)
        {
            ImportMethod(name, methodExpression);
        }

        public void ImportMethodWithParam<TParam>(string name, Expression<Action<TClass, TParam>> methodExpression)
        {
            ImportMethod<TClass, TParam>(name, methodExpression);
        }

        public void ImportMethodWithResult<TResult>(string name, Expression<Func<TClass, TResult>> methodExpression)
        {
            ImportMethod<TClass, TResult>(name, methodExpression);
        }
    }

    private static void TestImport()
    {
        ImportMethod<Foo>("MyMethod", f => f.Bar());
        ImportMethod<Foo, string>("MyMethod1", (f, p) => f.Bar(p));
        ImportMethod<Foo, bool>("MyMethod2", f => f.BarReturn());

        var helper = new ImportHelper<Foo>();
        helper.Import("MyMethod", f => f.Bar());
        helper.ImportMethodWithParam<string>("MyMethod1", (f, p) => f.Bar(p));
        helper.ImportMethodWithResult("MyMethod2", f => f.BarReturn());
    }

    public static void ImportMethod<TClass>(string name, Expression<Action<TClass>> methodExpression)
    {
        var method = GetMethodInfo(methodExpression.Body as MethodCallExpression);
        //Do what you want with the method.
    }

    public static void ImportMethod<TClass, TParam>(string name, Expression<Action<TClass, TParam>> methodExpression)
    {
        var method = GetMethodInfo(methodExpression.Body as MethodCallExpression);
        //Do what you want with the method.
    }

    public static void ImportMethod<TClass, TResult>(string name, Expression<Func<TClass, TResult>> methodExpression)
    {
        var method = GetMethodInfo(methodExpression.Body as MethodCallExpression);
        //Do what you want with the method.
    }

    private static MethodInfo GetMethodInfo(MethodCallExpression methodCallExpression)
    {
        if (methodCallExpression == null)
            return null;

        return methodCallExpression.Method;
    }

你想达到什么目标?您将如何使用这样的委托?@DanielHilgarth,我将通过反射检查它,并发出调用它的代码。那么首先为什么要使用委托?为什么不直接检查这个方法呢?这样我就可以有一个通用的方法,比如void ImportMethodstring name,委托代码,它可以将任何类型的方法导入到系统中。这会创建一个委托类型,当我想要System.Delegate类型的对象时,这样我就失去了方法的一般性。@我不明白你的意思。当您注册它时,您仍然有泛型,但是在调用委托的方法中,它只关心它返回一个int。否则,您可能试图在该方法中了解更多。您如何知道向每个方法传递什么?如何调用它们?因此用户必须使用反射来获取该方法的MethodInfo?@Impworks:是。通过提供助手方法,您可能可以稍微简化这一点。
void ImportMethod(string name, MethodInfo method)
void ImportMethod("Test", typeof(Test).GetMethod("Test", ...Static));
    public class Foo
    {
        public void Bar()
        {
        }

        public void Bar(string input)
        {
        }

        public bool BarReturn()
        {
            return false;
        }
    }

    public class ImportHelper<TClass>
    {
        public void Import(string name, Expression<Action<TClass>> methodExpression)
        {
            ImportMethod(name, methodExpression);
        }

        public void ImportMethodWithParam<TParam>(string name, Expression<Action<TClass, TParam>> methodExpression)
        {
            ImportMethod<TClass, TParam>(name, methodExpression);
        }

        public void ImportMethodWithResult<TResult>(string name, Expression<Func<TClass, TResult>> methodExpression)
        {
            ImportMethod<TClass, TResult>(name, methodExpression);
        }
    }

    private static void TestImport()
    {
        ImportMethod<Foo>("MyMethod", f => f.Bar());
        ImportMethod<Foo, string>("MyMethod1", (f, p) => f.Bar(p));
        ImportMethod<Foo, bool>("MyMethod2", f => f.BarReturn());

        var helper = new ImportHelper<Foo>();
        helper.Import("MyMethod", f => f.Bar());
        helper.ImportMethodWithParam<string>("MyMethod1", (f, p) => f.Bar(p));
        helper.ImportMethodWithResult("MyMethod2", f => f.BarReturn());
    }

    public static void ImportMethod<TClass>(string name, Expression<Action<TClass>> methodExpression)
    {
        var method = GetMethodInfo(methodExpression.Body as MethodCallExpression);
        //Do what you want with the method.
    }

    public static void ImportMethod<TClass, TParam>(string name, Expression<Action<TClass, TParam>> methodExpression)
    {
        var method = GetMethodInfo(methodExpression.Body as MethodCallExpression);
        //Do what you want with the method.
    }

    public static void ImportMethod<TClass, TResult>(string name, Expression<Func<TClass, TResult>> methodExpression)
    {
        var method = GetMethodInfo(methodExpression.Body as MethodCallExpression);
        //Do what you want with the method.
    }

    private static MethodInfo GetMethodInfo(MethodCallExpression methodCallExpression)
    {
        if (methodCallExpression == null)
            return null;

        return methodCallExpression.Method;
    }