1

I was looking around here for the answer to this question, and I found a lot of similar questions

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 method, Initializing 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

but I wasn't able to use any of them to solve my particular issue.

Basically, I have a class (that I don't want to modify) that is activated in a form like so:

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

I want to make a function that makes a new event listener "dynamically", meaning based on a particular variable for the "event type" (forget about the function body for now, just assume they all have the same function body), like:

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

as many of you will know, as did those people who posted the above questions, that simple doing that will give a "variable used like a type" error, and it won't work, and many of them suggested using "reflection" to get around this, like (from 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});

or (from 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();

So these answers theoretically make a class definition, but in my case I need to do 2 things, #1: make the actual class of the EventListener, and #2 actually give the class a body (via the lambda expression above), so how can I do that with Activator.CreateInstance ? Or Is there any other way?

Basically I can't use a lambda in the object[], because its not an object, and if I use an Action of some kind that is an object, then I would need to pass in a generic type, and I'm back to where I started, for example I could theoretically do:

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

which would compile, but then I'm back to where I started in the first place, because "KeyboardEvent" is itself what I need to change, and if I do:

Action<myDynamicTypeVariable>(e=>{})

I get the same "variable is used as type" error...

Isn't there just some kind of way to actually use a variable as a type?

Or is there a way to set the body of a function after the class instance has been formed?

Or how can I pass in a generic function as one of the object[] arguments without having to specify the type of the function and without using lambdas?

  • 1
    Look into [expression trees](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/expression-trees/). – Kenneth K. Jun 12 '19 at 23:10
  • @KennethK. so you mean create an "object" out of the lambda so I would be able to pass it in the object[] of arguments? But how would I make a generic function? For example on that page they have "Expression> lambda1 = Expression.Lambda>( .....(etc....)", but they start out with a Func, but in this case I would be doing, or example (as one of the object[] objects): new Action(e => {}), but then I would have to replace KeyboardEvent with a generic type again, and im back to where I started! – B''H Bi'ezras -- Boruch Hashem Jun 12 '19 at 23:20
  • How is `eventType` determined prior to calling `makeEvent`? – ChiefTwoPencils Jun 12 '19 at 23:28
  • @ChiefTwoPencils I simply pass it in like makeEvent(typeof(KeyboardEvent)) – B''H Bi'ezras -- Boruch Hashem Jun 12 '19 at 23:29
  • You can "set" the body of a function by composing functions. IOW, pass the body as a function. – ChiefTwoPencils Jun 12 '19 at 23:29
  • @ChiefTwoPencils can you give me an example that would fit this case? – B''H Bi'ezras -- Boruch Hashem Jun 12 '19 at 23:30
  • Not sure I can give you an example for your specific case based on your last edit limiting against lambdas and such though it can probably be done with extra verbosity. I'd have to play around with it and some generics but I'm not exactly sure I understand everything you're looking for. – ChiefTwoPencils Jun 12 '19 at 23:34
  • @ChiefTwoPencils I basically just want the first function definition (makeEvent) mentioned to compile. I, in theory, have nothing against lambdas, its only that when I pass it in the object[] as an argument, it gives me an error like "can't convert lambda to object" or something, so if you know how to get around that error, that would be good too – B''H Bi'ezras -- Boruch Hashem Jun 12 '19 at 23:35
  • @ChiefTwoPencils if you want to test out the exact code that I have then you can download PowerUI for Unity and see what I mean – B''H Bi'ezras -- Boruch Hashem Jun 12 '19 at 23:39
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/194845/discussion-between-chieftwopencils-and-bluejayke). – ChiefTwoPencils Jun 12 '19 at 23:39

0 Answers0