我有一些类和接口
public interface IGeoObject
{
GeoCoordinate GetGeocoordinate();
}
public class User : IGeoObject
{
public GeoCoordinate GetGeocoordinate()
{
//...
return GeoCoordinate;
}
}
public class Venue : IGeoObject
{
public GeoCoordinate GetGeocoordinate()
{
//...
return GeoCoordinate;
}
}
public class Place : IGeoObject
{
public GeoCoordinate GetGeocoordinate()
{
//...
return GeoCoordinate;
}
}
Run Code Online (Sandbox Code Playgroud)
我有,类型的示例变量用户 List<User>
我有签名的方法
double GetMinDistance(List<IGeoObject> objects, GeoCoordinate position)
Run Code Online (Sandbox Code Playgroud)
我无法传递用户GetMinDistance,因为泛型类型的协方差不起作用.
我可以创建额外的列表和使用方法.ConvertAll(或.CasT<T>):
List<IGeoObject> list = new List<User>(listUser).ConvertAll(x => (IGeoObject)x);
var dist = GeoTest.GetMinDistance(list, position);
Run Code Online (Sandbox Code Playgroud)
我不确定这是最优雅的解决方案.最令人尴尬的是调用者必须进行此转换.
这类似于我在架构中的问题?有更优雅的解决方案吗?
PS长篇故事,但我真的不能给出所有班级中同一物种的坐标.
那是因为List<T>不协变.
public class List<T> : IList<T>, ICollection<T>,
IList, ICollection, IReadOnlyList<T>, IReadOnlyCollection<T>, IEnumerable<T>,
IEnumerable
Run Code Online (Sandbox Code Playgroud)
如您所见,out类声明中没有关键字.
您必须使用它IEnumerable<T>来获得协方差支持.
public interface IEnumerable<out T> : IEnumerable
Run Code Online (Sandbox Code Playgroud)
那是因为List<T>有一组允许你修改集合的方法,并且使用协方差你将失去这些操作的编译类型安全性.IEnumerable<T>只允许你迭代集合,这就是为什么它可以被标记为协变.