How to get the type contained in a collection through reflection
In some part of my code I am passed a collection of objects of type T
. I don't know which concrete colletion I will be passed, other than it impements IEnumerable
.
At run time, I need to find out which type T is (e.g. System.Double
, System.String
, etc...).
Is there any way to find it out?
UPDATE: I should maybe clarify a bit more the context I am working in (a Linq Provider).
My function has a signature like the following, where I get the type of the collection as a parameter:
string GetSymbolForType(Type collectionType)
{
}
Is there any way from collectionType
to get the contain开发者_开发技巧ed objects type?
From Matt Warren's Blog:
internal static class TypeSystem {
internal static Type GetElementType(Type seqType) {
Type ienum = FindIEnumerable(seqType);
if (ienum == null) return seqType;
return ienum.GetGenericArguments()[0];
}
private static Type FindIEnumerable(Type seqType) {
if (seqType == null || seqType == typeof(string))
return null;
if (seqType.IsArray)
return typeof(IEnumerable<>).MakeGenericType(seqType.GetElementType());
if (seqType.IsGenericType) {
foreach (Type arg in seqType.GetGenericArguments()) {
Type ienum = typeof(IEnumerable<>).MakeGenericType(arg);
if (ienum.IsAssignableFrom(seqType)) {
return ienum;
}
}
}
Type[] ifaces = seqType.GetInterfaces();
if (ifaces != null && ifaces.Length > 0) {
foreach (Type iface in ifaces) {
Type ienum = FindIEnumerable(iface);
if (ienum != null) return ienum;
}
}
if (seqType.BaseType != null && seqType.BaseType != typeof(object)) {
return FindIEnumerable(seqType.BaseType);
}
return null;
}
}
myCollection.GetType().GetGenericArguments()
will return an array of the type args.
Type t = null
foreach(object o in list)
{
o.GetType();
}
will get you the type of the object.
Then you should probably test for your desired types:
if(t == typeof(myClass))
{
dosomething();
}
else if (t == typeof(myOtherClass))
{
dosomethingelse();
}
I use dynamic alot and this is an issue from time to time.
Matt Davis nailed it but you need the index :)
public static void PopulateChildCollection<T>(T currentObject, string singlePropertyName)
{
dynamic currentObjectCollection = ReflectionTools.GetPropertyValue(currentObject, singlePropertyName);
Type collectionType = currentObjectCollection.GetType().GetGenericArguments()[0];
The type will be what you would expect, it is the type of the object contained in the collection and not any of the generic types surrounding it.
Cant you just use t.GetType() to do this.
Why not just implement an IEnumerable<T>
instead? EG:
public void MyFunc<T>(IEnumerable<T> objects)
Other than that, you'd be better off checking the type of each individual object using is
or .GetType
rather than trying to work it out from the container itself.
If that's not an option though and you really need to know the type of the base container you'd basically have to check using is
to see what interfaces it implements (EG: IList<int>
etc). Odds are the type of your array is going to be a generic which means trying to work back from it's name down to it's data type will be quite messy.
Well I am way way late here but shouldn't this work :
public static bool ThatCollectionIsOfType<T>(IEnumerable<T> collection, Type got)
{
if (**typeof(T)** == got) //this line should be good to go...
{
return true;
}
}
精彩评论