I have an object of type X, which I can (obviously) retrieve in runtime.
var type = myObject.GetType();
And I have a generic static class.
public static class MyStaticClass<T>
{
public static void DoStuff(T something)
{
// bla bla
}
}
What I'd like to do is:
MyStaticClass<myObject.GetType()>.DoStuff(myObject);
But I can't.
In fact, there is just a few types on which MyStaticClass would operate, and they share several interfaces. One workaround is to write:
if (myObject.GetType() == typeof(X))
{
MyStaticClass<X>.DoStuff(myObject as X);
}
if (myObject.GetType() == typeof(Y))
{
MyStaticClass<Y>.DoStuff(myObject as Y);
}
but it's verbose, and writing that everywhere is really ugly - I feel that I shouldn't do that but also that I shouldn't have to do that.
I can't believe there is no solution. Or any neater workaround at least? Or is my approach wrong to start with (what's the alternative if so)? Should I create some (abstract?) base class for X, Y, Z?
This isn't possible without reflection, generic type parameters have to be known at compile time. Even though it is possible with reflection, I would advise against that. You should change your design.
"In fact, there is just a few types on which MyStaticClass would operate, and they share several interfaces. One workaround is to write:"
So can you not write the
DoStuff
method against the sharedinterface
's? That way you program against the known interface and are not trying to guess what type the object is. The whole approach seems a bit dodgy. Then you could remove the generics altogether.You can do this with reflection, using
Type.MakeGenericType
- but then you'll also need to use reflection to invoke the method. That's a bit of a pain though.If you're using C# 4 you could use dynamic typing and type inference - although that only works for generic methods rather than generic types, so you'd need to use:
EDIT: For performance, you can avoid doing too much actual reflection. You can perform reflection once per item type, create a delegate of the form
Action<object>
, and cache it in a dictionary. This can be far faster than performing reflection on every execution.Here's a short but complete sample:
I only use this sort of thing when I have to, but occasionally there really isn't any sensible alternative.