views:

363

answers:

2

Let's say I have the following class hierarchy: TaskViewer inherits from ListViewer<Task> which in turn inherits from ViewerBase.

If I debug into a method that is declared in ViewerBase and look at this.GetType(), it correctly returns TaskViewer. However, I cannot find a property or method which will return me the generic parameter that was used in the inheritance, i.e. Task. Obviously if I was in the context of TaskViewer or ListViewer<T> then I would easily know this.

I can see that it was Task by looking at the BaseType.FullName property, but I've been through the list and nothing I can see identifies itself as having used that generic argument.

How might I get the original generic parameter from within this method in the root class?

+4  A: 

You can access the generic argument of the base type as follows (assuming only a single type argument).

typeof(TaskViewer).BaseType.GetGenericArguments()[0]

In ViewerBase you would use

this.GetType().BaseType.GetGenericArguments()[0]

but it seems quite weired to look at the generic type arguments of a derived class in the base class. You cannot know waht the actual type is, hence not if it has generic arguments at all. Could you tell something about your usage scenario?

Daniel Brückner
Oh. I did try this and it was returning an empty Type array before, hence my posting this question. A rebuild and suddenly it returns the correct type!
tags2k
It's a module-based system, so in this case a ViewerBase-derived class somewhere has pointed an attribute at a static method that it wants to use as a source for its options list when it gets edited. The options rely on what T is, so the static method needs to know it. You can't pass typeof(T) in an attribute so it uses strings. I was writing the part that says "if there's a T in this string, search this class and its base class for generic parameters to pass into the option source method". If there's no T then I just call the method as normal. Hope that doesn't seem too weird! :-D
tags2k
+1  A: 

Make sure you're doing this for a good reason. If you're doing this to put the type returned in an if-statement and do something different depending on the type, this is a use for polymorphism, and possibly a generic constraint, not reflection.

It is for a good reason; the base class doesn't care about the type as it's already being constrained in the required ways. I'm actually parsing it out so I can pass it back into a MakeGenericMethod() call.
tags2k