2

If I have the following classes:

public class MyItems : List<MyItem>
{
..
}

public class MyItem : Item
{
..
}

How could I go about casting an instance of MyItems back down to List<Item>? I've tried doing an explicit cast and I get an exception.

itowlson
  • 73,686
  • 17
  • 161
  • 157
Jeremy
  • 44,950
  • 68
  • 206
  • 332

3 Answers3

8

You can't, because C# doesn't support generic variance (see here for discussion of terminology), and even if it did, it wouldn't allow this case, because if you could cast MyItems to List<Item>, you could call Add(someItemThatIsntAMyItem), which would violate type safety (because a MyItems can contain only MyItem objects, not arbitrary items).

See this question (or search SO for "c# generic variance") for additional information about this issue and future changes in C# 4 (though these will not affect your specific case).

Community
  • 1
  • 1
itowlson
  • 73,686
  • 17
  • 161
  • 157
0

I believe I saw that was coming in 4.0. Not available yet.

Brian Mains
  • 50,520
  • 35
  • 148
  • 257
  • 3
    Nope, won't be coming in 4.0 because (a) C# 4 supports variance only for delegates and interfaces, not classes (sigh) and (b) even if it did support variance on classes, it wouldn't be safe for `List` because T is in-out (variance is safe only if the type parameter appears only as inputs or only as outputs, not if it appears as both). – itowlson Jan 10 '10 at 06:03
0
public class MyList : IList<MyClass>
{
    List<MyClass> _list;


    //Implement all IList members like so
    public int IndexOf(MyClass item)
    {
        return _list.IndexOf(item);
    }


    //Then help the type system a bit with these two static methods.
    public static implicit operator List<MyClass> (MyList mylist)
    {
        return mylist._list;
    }

    public static implicit operator MyList (List<MyClass> list)
    {
        return new MyList() { _list = list;}
    }
Rodrick Chapman
  • 5,437
  • 2
  • 31
  • 32