tags:

views:

1172

answers:

3

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?

+3  A: 

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

Dustin Campbell
+12  A: 

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.

HTH, Kent

Kent Boogaart
+18  A: 

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.

John Feminella
I wish I could mark 2 accepted answers since I guess I did ask 2 questions.
Davy8
Don't worry, no hard feelings! StackOverflow is replete with good answers that aren't accepted. You picked the one that captured what you meant the most -- I'm just adding on a little extra info for the curious. ;)
John Feminella