Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get a base type of a IEnumerable [duplicate]

Tags:

c#

ienumerable

Possible Duplicate:
getting type T from IEnumerable<T>

I Have a property type of IEnumerable

public IEnumerable PossibleValues { get; set; }

How can I discover the base type that it was instanced?

For example, if it was created like this:

PossibleValues = new int?[] { 1, 2 }

I want to know that type is 'int'.

like image 391
Raoni Zacaron Avatar asked Oct 04 '12 13:10

Raoni Zacaron


2 Answers

Type GetBaseTypeOfEnumerable(IEnumerable enumerable)
{
    if (enumerable == null)
    {
        //you'll have to decide what to do in this case
    }

    var genericEnumerableInterface = enumerable
        .GetType()
        .GetInterfaces()
        .FirstOrDefault(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IEnumerable<>));

    if (genericEnumerableInterface == null)
    {
        //If we're in this block, the type implements IEnumerable, but not IEnumerable<T>;
        //you'll have to decide what to do here.

        //Justin Harvey's (now deleted) answer suggested enumerating the 
        //enumerable and examining the type of its elements; this 
        //is a good idea, but keep in mind that you might have a
        //mixed collection.
    }

    var elementType = genericEnumerableInterface.GetGenericArguments()[0];
    return elementType.IsGenericType && elementType.GetGenericTypeDefinition() == typeof(Nullable<>)
        ? elementType.GetGenericArguments()[0]
        : elementType;
}

This example has some limitations, which may or may not concern you in your application. It doesn't handle the case where the type implements IEnumerable but not IEnumerable<T>. If the type implements IEnumerable<T> more than once, it picks one implementation arbitrarily.

like image 61
phoog Avatar answered Oct 13 '22 23:10

phoog


You can do this if you want the type of PossibleValues:

var type = PossibleValues.GetType().ToString(); // "System.Nullable`1[System.Int32][]"

Or you can do this if you want the type of an item contained in PossibleValues (assuming the array actually has values as described in your question):

var type = PossibleValues.Cast<object>().First().GetType().ToString(); // "System.Int32"



EDIT

If it's a possibility that the array may contain no items, then you'll have to do some null checking, of course:

var firstItem = PossibleValues.Cast<object>().FirstOrDefault(o => o != null);
var type = string.Empty;
if (firstItem != null)
{
    type = firstItem.GetType().ToString();
}
like image 40
bugged87 Avatar answered Oct 13 '22 23:10

bugged87