Reputation: 607
public T getValueByName<T>(String name)
{
if( T is List )
Object containedType = T.WhatGoesHere()?
...
In the above code, I need to know if I can convert a List to whatever type of list is passed in, e.g., List<Control>
.
Is there a way to interrogate the generic for the contained type? I could get List<Control>
, List<String>
, List<Form>
etc..
I could split the API to return lists in a separate method where the contained type is passed in, thus requiring the caller to use one method for lists and one for simple types. Either way they have to know what's coming back, but if there's a smooth way to do what I'm asking about, I'd rather keep the API simple.
Note: this is a solution to the lack of covariance because even though there is an implicit conversion operator defined on the contained type, a cast of List to T fails. So, in order to follow the solution listOfB.Cast<A>();
from here, I need to know to what to cast (what is A).
Thanks!
Upvotes: 1
Views: 214
Reputation: 2540
You can start with typeof(T)
to get an instance of System.Type
that represents T
.
Once you have that, you can check Type.IsGenericType
to see if it really is a generic and then call Type.GetGenericArguments()
to see what generic arguments were used.
For example, if T
was List<int>
IsGenericType
would be true
and GetGenericArguments()
would return an array containing one element: System.Int32
For example, here is a snippet of code I wrote to see if a given type (variable type
) is some implementation if IEnumerable<T>
where T
is not known. It first has to see if it is a generic, then work out whether it has only one argument, determine said argument and see if it implements the interface, given that argument:
if (type.IsGenericType)
{
Type[] genericArguments = type.GetGenericArguments();
if (genericArguments.Length == 1)
{
Type proposedEnumerable = typeof(IEnumerable<>).MakeGenericType(genericArguments);
if (proposedEnumerable.IsAssignableFrom(type))
{
For reference, see:
Upvotes: 4