1

More specifically I have a Graph class, that contains a List of type Vertex . I have another class that extends Graph called Graph2D, I'd like to convert a List of type Vertex to a List of type Vertex2D on Graph2D.

Is this possible?

Edit:Answered by shf301. Thanks.

  • 1
    You can't cast, but you can convert. – Tamas Hegedus Aug 29 '15 at 01:52
  • You might want to consider making the `Graph` class generic on the type of Vertex. You should also take a look at MSDN on co- and contra- variance: https://msdn.microsoft.com/en-us/library/dd799517(v=vs.110).aspx to understand the limited circumstances when C# can help you with this problem. – Ian Mercer Aug 29 '15 at 02:00
  • You can't cast (explanation in [linked duplicate](http://stackoverflow.com/questions/2033912/c-sharp-variance-problem-assigning-listderived-as-listbase) ), so if you are fine with conversion/creating new - make sure to update your post so provided conversions answers can be on-topic and question can be re-opened. – Alexei Levenkov Aug 29 '15 at 02:38

2 Answers2

1

No it is not possible to cast a list to a list of it's subclasses. There is no reasonable way this could work without breaking type safety. Consider the following code if it were possible

List<Vertex> list1 = new List<Vertex>();
list1.Add(new Vertex());
List<Vertex2D> list2 = (List<Vertex2D>)list1;
Vertex2D vertex2d = list2[0];  // Oh no the first element is a Vertex!

The list list would have to throw an InvalidCastException since you can't convert a Vertex to a Vertex2D.

However I suspect that your real issue is you want the list of vertex's in Vertex2D that was inherited from Vertex to change type. This is you have:

class Graph {
     public List<Vertex> Vertices { get; set; }
}

class Graph2D : Graph {
    // Now I want vertices to only contain Vertex2D!
}

You can accomplish this my making Graph generic on Vertex:

class GraphBase<TVertex> where TVertex : Vertex {
     public List<TVertex> Vertices { get; set; }
}

class Graph : GraphBase<Vertex> {
}

class Graph2D : GraphBase<Vertex2D> {
}

This does break the inheritance relationship between Graph and Graph2D. If that's important I'd suggest implementing a non-generic interface. This interface can rely on the fact that IEnumerable is covariant on T:

interface IGraph {
     IEnumerable<Vertex> Vertices { get;}
}

 class GraphBase<TVertex> : IGraph where TVertex : Vertex {
     public List<TVertex> Vertices { get; set; }
     IEnumerable<Vertex> IGraph.Vertices { get { return Vertices; }}
}
shf301
  • 31,086
  • 2
  • 52
  • 86
-1

Linq to the rescue!!

var casted = TheVertexList.Cast<Vertex2D>().ToList();
Gusman
  • 14,905
  • 2
  • 34
  • 50