如何从泛型函数

时间:2017-12-23 19:02:50

标签: c# generics reflection

给出以下代码:

int result = Execute(() => Foo(1, 2));

public int Foo(int x, int y)
{
    return x + y;
}

public T Execute<T>(
    Func<T> function)
{
    Console.Write(function.Method.Name + ": " + string.Join(", ", params));
    return function();
}

是否可以获取参数?所以输出会读取如下内容:

“Foo:1,2”

1 个答案:

答案 0 :(得分:1)

是的,你可以。使用表达式树。但请注意,它并未涵盖所有情况(LINQ等链式调用)。它总是可以安排覆盖那些情况,但这种方法将变成巨大的垃圾堆:

class Program
{
    static void Main(string[] args)
    {
        int result = Execute(() => Foo(1, 2));
    }

    public static int Foo(int x, int y)
    {
        return x + y;
    }

    public static T Execute<T>(Expression<Func<T>> function)
    {
        var call = function.Body as MethodCallExpression;
        var values = new List<object>();
        var obj = call.Object == null ? null : Expression.Lambda(call.Object).Compile().DynamicInvoke();
        foreach (var arg in call.Arguments)
        {
            var value = Expression.Lambda(arg).Compile().DynamicInvoke();
            values.Add(value);
        }
        LogMethodCall(call.Method.Name, values);
        return (T)call.Method.Invoke(obj, values.ToArray());
    }

    public static void LogMethodCall(string methodName, IEnumerable<object> args)
    {
        Console.WriteLine("{0}: {1}", methodName, string.Join(",",args.Select(x=> x.ToString())));
    }
}

它会打印出来:

  

Foo:1,2

在此示例中,您还可以记录invokation的输出和对象。