Reputation: 170
I'm hoping someone can suggest a way to avoid the explicit cast for the "var o3" statement below. It seems the compiler should have sufficient information to implicitly cast.
using System.Collections.Generic;
namespace Sample {
public interface IPoint {
double X { get; }
double Y { get; }
}
public class Line<T> :List<T> where T:IPoint {}
public class Graph<T> where T :IPoint {
public Line<IPoint> Line1;
public Line<T> Line2;
public Graph() {
var o1 = new Other(Line1); //works
var o2 = new Other(Line2 as IEnumerable<IPoint>); //works
var o3 = new Other(Line2); //error: cannot convert from 'Sample.Line<T>' to 'IEnumerable<Sample.IPoint>'
}
}
public class Other {
public Other(IEnumerable<IPoint> list) {}
}
}
Upvotes: 4
Views: 294
Reputation: 34285
You need to add class
constraint on T
type argument of Graph<T>
class:
public class Graph<T> where T : class, IPoint
This is because covariance doesn't work with structs:
new List<Int32>() is IEnumerable<IConvertible> == false
new List<String>() is IEnumerable<IConvertible> == true
although both Int32
and String
implement IConvertible
.
See Why covariance and contravariance do not support value type.
Upvotes: 4