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

时间:2013-04-04 14:06:26

标签: c# .net generics delegates

我有一个简单的课程:

class Test
{
    public static int Test<T>(T arg)
    {
        return 1;
    }
}

我想获得一个代表此方法的Delegate类型的对象。是否可以创建这样的委托?如果我可以将包含任意数量参数和泛型参数的方法转换为Delegate,那就更好了。

4 个答案:

答案 0 :(得分:2)

您不想在此处使用委托。您想要一个MethodInfo实例:

void ImportMethod(string name, MethodInfo method)

你会这样称呼:

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

答案 1 :(得分:1)

如果使用泛型编写方法来保持类型安全,则需要为每个具有不同输入参数的方法编写两个方法,一个用于void方法(Action),另一个用于返回值的方法( FUNC)。 我投入了一个辅助类,因为它减少了每个方法导入必须传递的泛型参数的数量。调用方法时,它也有助于智能感知。

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

答案 2 :(得分:0)

好像您正在寻找FuncAction

您可以使用以下内容获取“委托对象”

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

您可以使用

void ImportMethod(string name, Action action)

void ImportMethod(string name, Func<int> func)

取决于您是否需要返回值并按此注册

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

答案 3 :(得分:0)

public delegate int Del<T>(T item);