将lambda或方法组转换为Action <t>,其中T仅在运行时已知</t>

时间:2014-04-30 19:34:38

标签: c# generics types lambda type-conversion

我从运行时传递给我的字符串中动态创建一个类型。

目前我有以下代码:

string messageType = "CustomerCreatedMessage";
//Convert the string to a Type
var type = Type.GetType(messageType);
//Create a Type of Action<CustomerCreatedMessage>
var action = typeof(Action<>).MakeGenericType(messageType);

我如何创建action类型的变量并将lambda m=> SetActive(true)分配给它?然后,我将在以下代码中使用变量(此处名为???):

//Create a generic method "Register" on my Messenger class that takes an Action<CustomerCreatedMessage> parameter.
var method = typeof(Messenger).GetMethod("Register");
var genericMethod = method.MakeGenericMethod(action);
//Invoke the created method with our script in it
genericMethod.Invoke(Messenger.Default, ???);

我的目标是能够使用Messenger.Default.Register<>调用我的通用方法Action<>,该方法将从messageType字符串创建的类型作为类型参数。

我已经尝试了以下内容:

Convert.ChangeType(m=>SetActive(true),action);

var filledAction = Activator.CreateInstance(action);
filledAction = m=>SetActive(true);

但是这两种方法都抱怨将lambda表达式转换为对象,因为它不是委托。

如果我将SetActive(true)放入方法并尝试传递方法组,我会收到类似的错误。

1 个答案:

答案 0 :(得分:2)

鉴于您根本没有使用该参数,我将创建一个新的通用方法:

private static void GenericSetActive<T>(T ignored)
{
    SetActive(true);
}

然后使用它创建一个委托:

var genericMethod = typeof(Foo).GetMethod("GenericSetActive",
                                          BindingFlags.NonPublic |
                                          BindingFlags.Static);
var concreteMethod = genericMethod.MakeGenericMethod(type);
var actionInstance = Delegate.CreateDelegate(action, concreteMethod);

基本上,你不能在这里使用lambda表达式,因为你没有特定的委托类型来将其转换为。