Basically, my question is: Is there some way to "recover" a type parameter that was lost by upcast to a non-generic base type, e.g., Object. Here is an example of what I mean:
Consider I have received an Object l from a library and I know that l is an IList<T>, but I do not know the T (but I do know that it is a reference type, no value type). However, the exact type of T is not important, because all I want to do is to pass l to a generic method:
void doSomethingWithList<T>(IList<T> l){ ... }
However, I cannot do that, since I do not know to which type to cast l, i.e., I would like to do the following:
doSomethingWithList((IList<>)l);
I want to tell the compiler that l is an IList and it should call the method and bind the unknown type parameter to its parameter T. But it doesn't work like this. Do I have any options? Can I somehow pass an object for which I "lost" the type parameter to a generic method?
You can do it using reflection:
var interfaceType = l.GetType().GetInterface("System.Collections.Generic.IList`1");
var itemType = interfaceType.GetGenericArguments()[0]; // This is your T
var method = this.GetType().GetMethod("doSomethingWithList").MakeGenericMethod(itemType);
method.Invoke(this, new object[] { l });
But if you can, it's probably better to change doSomethingWithList to accept a non-generic list...
If you know it's safe, the simplest solution is to use dynamic:
doSomethingWithList((dynamic)l);
Otherwise you could check that l implements IList<T> for some T and call the method through reflection:
var listType = l.GetType().GetInterfaces().FirstOrDefault(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IList<>));
if (listType != null)
{
Type elementType = listType.GetGenericArguments()[0];
var method = this.GetType().GetMethod("doSomethingWithList").MakeGenericMethod(elementType);
method.Invoke(this, new object[] { l });
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With