18

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?

jerryjvl
  • 19,723
  • 7
  • 40
  • 55
Davy8
  • 30,868
  • 25
  • 115
  • 173
  • Not sure quite what you're trying to achieve here. Could you provide more context and/or an explanation of what SomeMethod needs to do (and why it needs to do it for a list of types), please? – Noldorin Mar 14 '09 at 17:59
  • Yeah you can do that with reflection as other have mentioned but keep in mind that reflection is bloody slow. If performance is important in your case, consider some other approach. – Tamas Czinege Mar 14 '09 at 18:02
  • I need to index all the types in our object database without worrying about when new types are added or removed, etc – Davy8 Mar 14 '09 at 18:04
  • I see. If you just want to index the types, why not just pass the System.Type object to a method? – Noldorin Mar 14 '09 at 18:05
  • Well, if I were you, I would just pass the type as a regular parameter. In the end, generic type parameters are almost like parameters, but you will have to use reflection to be able to set them in your case so consider using plain parameters of type "Type" – Tamas Czinege Mar 14 '09 at 18:07
  • Yeah, probably going to have to just pass it as a parameter. Due to the structure of things, there's a a fair amount of code to write since the generic methods are already in written and cascade fairly deep down the inheritance tree. – Davy8 Mar 14 '09 at 18:10

3 Answers3

24

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.

Sheridan
  • 68,826
  • 24
  • 143
  • 183
Kent Boogaart
  • 175,602
  • 35
  • 392
  • 393
23

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
  • 303,634
  • 46
  • 339
  • 357
  • 3
    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 Mar 14 '09 at 18:17
  • Now that C# 4 has been released can you update your answer with a example using `dynamic` – Scott Chamberlain Jul 26 '14 at 01:04
  • 1
    The example of using dynamic is: SomeMethod((dynamic)someType); – nightcoder Feb 03 '15 at 22:00
  • @nightcoder if SomeMethod has a parameter of someType this works great, but what if there are no further parameters like in the example? – Felix Keil Sep 16 '16 at 12:15
3

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

Community
  • 1
  • 1
Dustin Campbell
  • 9,747
  • 2
  • 31
  • 32