C#使用<SomeType>激活类,并根据“类型”变量动态地创建主体

时间:2019-06-12 23:06:49

标签: c# generics types

我在这里寻找这个问题的答案,并且发现了很多类似的问题

Passing just a type as a parameter in C#

X is a variable but used like a type when trying to cast

how to adjust "is a type but is used like a variable"?

How to pass an Object type to Type parameter in C#

Generic List<T> as parameter on methodInitializing a Generic variable from a C# Type Variable

How do I use reflection to call a generic method?

Reflection To Execute Class With Generic Type

但是我无法使用它们中的任何一个来解决我的特定问题。

基本上,我有一个类(我不想要修改),该类的激活方式如下:

var myEvent = new EventListener<KeyboardEvent/*or other type of event*/>((e) => {
    ///do stuff with event "e"
});

我想创建一个使“动态”创建新事件侦听器的函数,这意味着基于“事件类型”的特定变量(暂时不使用函数体,只需假设它们都具有相同的函数体) ,例如:

void makeEvent(Type eventType) {
    var myEvent = new EventListener<eventType>((e) => {
        ///do stuff with event "e"
    });
}

就像您发布上述问题的人一样,许多人都知道,这种简单的操作会产生“像类型一样使用变量”错误,并且不会起作用,许多人建议使用“反射”来解决此问题,例如(来自Reflection To Execute Class With Generic Type):

ar instance = Activator.CreateInstance(implementation);
        var results = this.GetType()
            .GetMethod("CheckForMessages", BindingFlags.NonPublic | BindingFlags.Instance)
            .MakeGenericMethod(interfaceUsesType)
            .Invoke(this, null) as object[];

        if(results.Count() > 0)
            instance.GetType()
            .GetMethod("DoThis")
            .Invoke(instance, new object[] {results});

或(来自Initializing a Generic variable from a C# Type Variable):

Animal a = MyFavoriteAnimal();
var contextType = typeof(EsbRepository<>).MakeGenericType(a.GetType());

dynamic context = Activator.CreateInstance(contextType);
context.DoAnimalStuff();

因此,从理论上讲,这些答案构成了一个类定义,但是在我的情况下,我需要做两件事:#1:制作EventListener的实际类,而#2实际上给该类一个 body (通过上面的lambda表达式),那么如何使用Activator.CreateInstance做到这一点?还是还有其他方法?

基本上,我不能在object []中使用lambda,因为它不是对象,并且如果我使用某种类型的Action作为对象,那么我将需要传递泛型,并且回到我的起点,例如,理论上我可以做到:

var myType = typeof(EventListener<>).MakeGenericType(eventType);
Activator.CreateInstance(myType, new object[] {
   new Action<KeyboardEvent>(e => {})
});

这将进行编译,但是我回到了最初的地方,因为“ KeyboardEvent”本身就是我需要更改的东西,并且如果需要的话:

Action<myDynamicTypeVariable>(e=>{})

我收到相同的“变量用作类型”错误...

难道不存在某种实际上将变量用作类型的方法吗?

或者在类实例形成之后是否有办法设置函数的主体?

或者如何在不指定函数类型且不使用lambda的情况下将通用函数作为object []参数之一传递呢?

0 个答案:

没有答案