Why is List <int> not IEnumerable <ValueType>?

[Edit: My apologies ... the original wording of the question was ambiguous, and I did not receive the answers I am looking for)

For any class X that inherits from class Y, new List<X>() is IEnumerable<Y>is true. However, this does not apply to structs: new List<int>() is IEnumerable<ValueType>false. My question is why?

Here is an example program:

class Program
{
    class Y { }
    class X : Y { }
    struct Z { }

    static void Main(string[] args)
    {
        Test(new List<X>());
        Test(new List<string>());
        Test(new List<Z>());
        Test(new List<int>());
        Test("blah");
        Test(1);
        Console.ReadLine();
    }

    static void Test(object o)
    {
        if (o is IEnumerable<Y>)
        {
            Console.WriteLine(o + " is a list of Ys");
        }
        else if (o is IEnumerable<ValueType>)
        {
            Console.WriteLine(o + " is a list of ValueTypes");
        }
        else if (o is IEnumerable<object>)
        {
            Console.WriteLine(o + " is a list of objects");
        }
        else if (o is System.Collections.IEnumerable)
        {
            Console.WriteLine(o + " is most likely a list of ValueTypes or a string");
        }
        else
        {
            Console.WriteLine(o + " is not a list");
        }

    }
}

Conclusion:

System.Collections.Generic.List`1 [ConsoleApplication1.Program + X] is a list of Ys

System.Collections.Generic.List`1 [System.String] is a list of objects

System.Collections.Generic.List`1 [ConsoleApplication1.Program + Z] is most likely a list of ValueTypes or strings

System.Collections.Generic.List`1 [System.Int32] is most likely a list of ValueTypes or strings

blah is most likely a ValueTypes list or string

1 is not a list

, new List<int> a IEnumerable<ValueType>?

+5
6

, . , List<string> IEnumerable<object>, string , List<int> IEnumerable<ValueType>. . 13.1.3.2 #.

+7

iArr ( iArr[i]); , , . .

? , int ValueType? , ; a int! , , ( , , ), .

+1

, , , List<x> List<y>, x y , , true . List<T>.

x y, RandomGeneric<x> RandomGeneric<y>, themselvs.

List<x> List<y> ( , ). IEnumerable<x> IEnumerable<y>.

+1

. iArr , int. , , , - . , , .

.

IEnumerable arse = SomeMethodThatReturnsIEnumerable();    
bool areAllValueTypes = arse.<OfTypeobject>().All(x => x is ValueType);
0

, .

var lst = new List<Object>();
lst.Add(1);
lst.Add(3);

, ValueTypes. true false? false, :

private bool attemptOne(IEnumerable coll)
{
    var s = coll.GetType().GetGenericArguments()[0];
    return s.IsValueType;
}

var lstTwo = new List<int>();
lstTwo.Add(1);
lstTwo.Add(3);
Console.WriteLine(attemptOne(lstTwo)); // Returns true

true, :

private bool attemptTwo<T>(IEnumerable<T> coll)
{
    return coll.All(c => c.GetType().IsValueType);
}

, .

0

, ,

bool IsCollectionOfValueTypes(Object argValue)
{
  Type t = argValue.GetType();
  if(t.IsArray)
  {
    return t.GetElementType().IsValueType;
  }
  else
  {
    if (t.IsGeneric)
    {
      Types[] gt = t.GetGenericArguments();
       return (gt.Length == 1) && gt[0].IsValueType;
    }
  }
  return false;
}

In any case, the beginning can be a little complicated if you pass a multidimensional array or a configured type. All this in the classroom somewhere though.

0
source

All Articles