C#创建方法的委托,其中参数类型在运行时未知

时间:2014-10-31 08:38:34

标签: c# types parameters delegates runtime

我要做的是以下(我必须不知道它是否可能);我知道运行时类型。我知道我想在运行时调用哪种方法。但是,我在编译时不知道这一点。

GetFunction方法无法创建给定methodInfo的委托,因为inparam不是object类型。

有没有办法创建一个函数的委托,我只知道我想委派的方法的Type和MethodInfo?

public sealed class Functions {
    public static int SetStrValue(string s) {
        // set a string
    }

    public static int SetIntValue(int i) {
        // set an int
    }
}

public sealed class GetFunctions {
    public Func<object, int> GetFunction(Type type, MethodInfo methodInfo) {
        // what I would like to do.
        Func<object, int> func = Delegate.CreateDelegate(typeof(Func<object, int>), methodInfo);
        return t => func(t);
    }
}

public class InvokeFunctions {
    public void invokeFunction() {
        Type t = typeof(String);
        MethodInfo methodInfo = typeof(Functions).GetMethod("SetStrValue");
        int i = GetFunctions.GetFunction(t, methodInfo).Invoke("hello");
    }
}

2 个答案:

答案 0 :(得分:3)

您可以使用表达式树来创建委托。由于编译时类型未知,您可以尝试在运行时将参数强制转换为适当的类型。

public sealed class GetFunctions
{
    public static Func<object, int> GetFunction(MethodInfo methodInfo)
    {
        var obj = Expression.Parameter(typeof (object), "obj");
        var convert = Expression.Convert(obj, methodInfo.GetParameters().First().ParameterType);
        var call = Expression.Call(methodInfo, convert);
        var lambda = Expression.Lambda<Func<object, int>>(call, obj);

        return lambda.Compile();
    }
}

public class InvokeFunctions
{
    public void invokeFunction()
    {
        MethodInfo methodInfo = typeof(Functions).GetMethod("SetStrValue");
        int i = GetFunctions.GetFunction(methodInfo).Invoke("hello");

        MethodInfo methodInfo2 = typeof(Functions).GetMethod("SetIntValue");
        int i2 = GetFunctions.GetFunction(methodInfo2).Invoke(1);
    }
}

我删除了Type参数并直接从Method的第一个参数中获取,如果这不是预期的行为,则可以更改它。

答案 1 :(得分:0)

您可以使用泛型将其简化为:

public sealed class Functions 
{
    public static int SetValue<T>(T input) 
    {
        // set a value of type T
    }
}

用以下方法调用该函数:

Functions.SetValue<string>("hello");

如果您仍想使用委托,则可以使用通用委托定义:

public delegate int MyDelegateFunction<T>(T input);