Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can you use generics methods in C# if the type is unknown until runtime?

Tags:

c#

types

generics

Easiest way to explain what I mean is with a code sample. This doesn't compile, but is there any way to achieve this effect:

foreach(Type someType in listOfTypes)
{
    SomeMethod<someType>();
}

Would be really convenient if that would work, but it doesn't. Is there another way to achieve the same thing as above, and why doesn't C# allow for that to be a legal statement?

Edit: Seems like the only way to do this is via reflection which may be too slow for our needs. Any insight on why there's not an efficient way built in and whether something like this is in the works for C# 4.0?

like image 529
Davy8 Avatar asked Mar 14 '09 17:03

Davy8


People also ask

Can you do generics in C?

Unlike C++ and Java, C doesn't support generics. How to create a linked list in C that can be used for any data type? In C, we can use a void pointer and a function pointer to implement the same functionality.

Can we have generic method in non generic class?

Yes, you can define a generic method in a non-generic class in Java.

How do I create a generic method in C sharp?

You can create an instance of generic classes by specifying an actual type in angle brackets. The following creates an instance of the generic class DataStore . DataStore<string> store = new DataStore<string>(); Above, we specified the string type in the angle brackets while creating an instance.

What are not allowed for generics?

Cannot Use Casts or instanceof With Parameterized Types. Cannot Create Arrays of Parameterized Types. Cannot Create, Catch, or Throw Objects of Parameterized Types. Cannot Overload a Method Where the Formal Parameter Types of Each Overload Erase to the Same Raw Type.


3 Answers

You can use reflection. Assuming the current object contains the SomeMethod() method, the code to do so would look like this:

GetType().GetMethod("SomeMethod").
    MakeGenericMethod(new Type[] { someType }).Invoke(this, null);

Note that if SomeMethod() is non-public, your code may not execute in lower-trust environments.

like image 91
Kent Boogaart Avatar answered Oct 01 '22 01:10

Kent Boogaart


Why doesn't C# allow for that to be a legal statement?

As others have noted, you can't do this. Why not? Well, consider your example:

foreach(Type someType in listOfTypes)
{
    SomeMethod<someType>();
}

Notice that each type in the list of types cannot be known until runtime, whereas the type parameter of SomeMethod must be known at compile time. It is impossible for the compiler to tell which SomeMethod<T> to resolve your invocation to, so this is illegal.

In C# 4, this and many other similar things will be possible with the inclusion of the DLR into the CLR. In particular, dynamic method invocation will enable you to invoke methods that may not be known at compile time.

like image 33
John Feminella Avatar answered Oct 01 '22 01:10

John Feminella


The only way to do this today is via reflection. See MethodInfo.MakeGenericMethod(Type[]).

like image 36
Dustin Campbell Avatar answered Oct 01 '22 00:10

Dustin Campbell