views:

174

answers:

5

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 contained objects type?

A: 
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();
}
BeowulfOF
A: 

Cant you just use t.GetType() to do this.

Joel Cunningham
A: 

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.

Tim Schneider
A: 
myCollection.GetType().GetGenericArguments()

will return an array of the type args.

nitzmahone
only works on generic types.
BeowulfOF
+1  A: 

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;
    }
}
dtb
This did the trick. Thank you.
Stefano Ricciardi