我有一些类和接口(interface)
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;
}
}
我有类型为 List<User>
的示例变量用户
我有带签名的方法
double GetMinDistance(List<IGeoObject> objects, GeoCoordinate position)
我无法将用户传递给 GetMinDistance
,因为泛型类型的协变不起作用。
我可以创建额外的列表并使用方法 .ConvertAll
(或 .CasT<T>
):
List<IGeoObject> list = new List<User>(listUser).ConvertAll(x => (IGeoObject)x);
var dist = GeoTest.GetMinDistance(list, position);
我不确定这是最优雅的解决方案。最尴尬的是,调用者必须执行此转换。
这和我在架构上的问题类似?还有更优雅的解决方案吗?
附言说来话长,但我真的不能给出所有类中同一物种的坐标。
最佳答案
那是因为 List<T>
不是协变的。
public class List<T> : IList<T>, ICollection<T>,
IList, ICollection, IReadOnlyList<T>, IReadOnlyCollection<T>, IEnumerable<T>,
IEnumerable
如您所见,没有 out
类声明中的关键字。
你必须使用 IEnumerable<T>
而不是获得协方差支持。
public interface IEnumerable<out T> : IEnumerable
那是因为 List<T>
有一组允许您修改集合的方法,并且通过协变,您将失去这些操作的编译类型安全性。 IEnumerable<T>
只允许您迭代集合,这就是它可以标记为协变的原因。
关于c# - 通用集合 C# 中的协方差,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19506511/