Linq 以列表语法对接口进行编码
我已将一些具体类提取到接口中 我曾经有一个名为City的类,它实现了接口 现在我试着做下面的事情Linq 以列表语法对接口进行编码,linq,c#-4.0,interface,Linq,C# 4.0,Interface,我已将一些具体类提取到接口中 我曾经有一个名为City的类,它实现了接口 现在我试着做下面的事情 public List<ICity> Cities { get; private set; } var efCities = (from c in myentity.Cities orderby c.CityName select c); Cities = (efCities.Select(o => n
public List<ICity> Cities { get; private set; }
var efCities = (from c in myentity.Cities
orderby c.CityName
select c);
Cities = (efCities.Select(o => new City() { Id = o.Id, Country = o.Country,
Province = o.Province, CityName = o.CityName }).ToList());
遗憾的是,泛型类型参数与独立类型不遵循相同的类型转换规则。它们受到泛型类型所允许的内容的限制;这称为协变和逆变,在C语言中,只有数组、接口和委托可以是协变或逆变的。从C4.0开始,像List这样的具体类型不能至少为 泛型不能以您通常认为的方式工作的原因是,不可能知道泛型类型使用其类型参数做了什么;协方差是直观的,因为这就是简单赋值的工作原理,但在许多情况下,我们真正想要的是逆变换;因为编译器不能为我们做出决定,除非您另有说明,否则它默认为两者都不做 有关C4中协方差/逆变的更多信息,我建议您查看Eric Lippert的一系列文章,特别是: 以及MSDN关于它的文章: 幸运的是,在本例中有一个简单的答案,即显式IEnumerable.Cast方法:
遗憾的是,泛型类型参数与独立类型不遵循相同的类型转换规则。它们受到泛型类型所允许的内容的限制;这称为协变和逆变,在C语言中,只有数组、接口和委托可以是协变或逆变的。从C4.0开始,像List这样的具体类型不能至少为 泛型不能以您通常认为的方式工作的原因是,不可能知道泛型类型使用其类型参数做了什么;协方差是直观的,因为这就是简单赋值的工作原理,但在许多情况下,我们真正想要的是逆变换;因为编译器不能为我们做出决定,除非您另有说明,否则它默认为两者都不做 有关C4中协方差/逆变的更多信息,我建议您查看Eric Lippert的一系列文章,特别是: 以及MSDN关于它的文章: 幸运的是,在本例中有一个简单的答案,即显式IEnumerable.Cast方法: 不,列表和列表不一样。而不是指定select.toList;要访问城市,请尝试以下操作: Cities.AddRangeefCities.Selecto=>新城市{Id=o.Id,Country=o.Country,Province=o.Province,CityName=o.CityName}否。列表与列表不同。而不是指定select.toList;要访问城市,请尝试以下操作: Cities.AddRangeefCities.Selecto=>新城市{Id=o.Id,Country=o.Country,Province=o.Province,CityName=o.CityName}它与
ICity c = new City();
List和List是TechSelves类型,List不是从List派生的
向选择中添加强制转换可以解决以下问题:
Cities = (efCities.Select(o => (ICity)(new City() { Id = o.Id, Country = o.Country,
Province = o.Province, CityName = o.CityName })).ToList());
这与
ICity c = new City();
List和List是TechSelves类型,List不是从List派生的
向选择中添加强制转换可以解决以下问题:
Cities = (efCities.Select(o => (ICity)(new City() { Id = o.Id, Country = o.Country,
Province = o.Province, CityName = o.CityName })).ToList());
没有人真正说出这不起作用的原因。假设Apple和Orange都实现了IFruit:
List<Orange> oranges = new List<Orange>();
List<IFruit> fruits = oranges; // You are trying to do this, which is illegal.
// Suppose it were legal. Then you could do this:
fruits.Add(new Apple());
这是一种不安全的协方差。我们决定不允许对接口使用相同的危险模式;只有在编译器能够证明这样的错误是不可能的情况下,接口才能是协变的。没有人真正说出这不起作用的原因。假设Apple和Orange都实现了IFruit:
List<Orange> oranges = new List<Orange>();
List<IFruit> fruits = oranges; // You are trying to do this, which is illegal.
// Suppose it were legal. Then you could do this:
fruits.Add(new Apple());
这是一种不安全的协方差。我们决定不允许对接口使用相同的危险模式;只有在编译器能够证明这种错误是不可能的情况下,接口才能是协变的。pfft。为什么要给别人一个明确的解释和多种选择,而你可以扔掉一些东西,得到15个代表\TL;jk博士-我给了你+1。有些人只是想要答案,有些人想要解释。耸耸肩我会撤销我的回答,因为它未经测试。不要这样做。这是对的,它只是不完全是被要求的;说它不正确实在是太苛刻了。为了简洁起见,总有一些话要说:为了完整起见,可以把我的评论编辑成你的答案吗?答案正确比谁给出的更重要。为什么要给别人一个明确的解释和多种选择,而你可以扔掉一些东西,得到15个代表\TL;jk博士-我给了你+1。有些人只是想要答案,有些人想要解释。耸耸肩我会撤销我的回答,因为它未经测试。不要这样做。这是对的,它只是不完全是被要求的;说它不正确实在是太苛刻了。为了简洁起见,总有一些话要说:为了完整起见,可以把我的评论编辑成你的答案吗?有正确的答案比谁给出的更重要。仅供参考:确保你打电话给城市。如果你必须多次运行此代码,请清除,否则它将复制你的列表内容,而不是替换它们。只需 仅供参考:确保您呼叫城市。如果您必须多次运行此代码,请清除,否则它将复制您的列表内容,而不是替换它们。
Orange[] oranges = new Orange[1];
IFruit[] fruits = oranges; // dangerous, but legal!
fruits[0] = new Apple(); // legal at compile time, crashes at runtime.