Cru*_*ler 1 linq interface c#-4.0
我已经将一些具体的类提取到接口中
我曾经有一个叫做的类City,它实现了接口ICity
现在我试着做以下事情
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());
Run Code Online (Sandbox Code Playgroud)
我得到以下调整:
无法隐式转换类型
'System.Collections.Generic.List<City>'到'System.Collections.Generic.List<ICity>'
据我了解,因为City工具ICity,我应该没事,不是吗?不是我正在做的事情和去的一样:
ICity c = new City();
Run Code Online (Sandbox Code Playgroud)
Eri*_*ert 10
没有人真的说过这不起作用的原因.假设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());
Run Code Online (Sandbox Code Playgroud)
因为您可以将苹果添加到水果列表中,但该列表实际上是橙色列表!你只需将苹果放入橙子列表中,而苹果不是橙子.
C#编译器知道这可能发生,所以它不允许它.不幸的是,它并不禁止数组:
Orange[] oranges = new Orange[1];
IFruit[] fruits = oranges; // dangerous, but legal!
fruits[0] = new Apple(); // legal at compile time, crashes at runtime.
Run Code Online (Sandbox Code Playgroud)
这是一种不安全的协方差.我们决定不允许接口使用相同的危险模式; 如果编译器可以证明这样的错误是不可能的,那么接口只能是协变的.
遗憾的是,泛型类型参数不遵循与独立类型相同的类型转换规则.它们受到通用类型所允许的限制; 这称为协方差和逆变,并且在C#中,只有数组,接口和委托可以是协变的或逆变的.类似的具体类型List不能(至少从C#4.0开始).
(泛型不能按照你一般认为的方式工作的原因是因为它不可能知道泛型类型对其类型参数的作用;协方差是直观的,因为这是简单的任务有效,但在许多情况下我们真正想要的是逆变;由于编译器无法为我们做出决定,因此除非您另有说明,否则默认为.)
有关C#4中共同/逆转的更多信息,我建议您查看Eric Lippert关于它的一系列帖子,特别是:
以及关于它的MSDN文章:
http://msdn.microsoft.com/en-us/library/dd799517.aspx
幸运的是,在这种情况下有一个简单的答案,显式IEnumerable.Cast方法:
Cities = (efCities.Select(o => new City() { Id = o.Id, Country = o.Country,
Province = o.Province, CityName = o.CityName }).Cast<ICity>.ToList());
Run Code Online (Sandbox Code Playgroud)
另一个选择是使用IEnumerable<T>而不是List<T>.IEnumerable<T> 是协变的,T所以你的任务将起作用:
interface IA
{
int Foo();
}
class A : IA
{
public int Foo()
{
return 0;
}
}
public DoStuff()
{
List<A> la = new List<A> { new A(), new A(), new A(), new A() };
// This is an error -- List<A> is not covariant with List<IA>
// List<IA> lia = la;
// This is fine; List<A> implements IEnumerable<A>
IEnumerable<A> iea = la;
// Also fine: IEnumerable<A> is covariant with IEnumerable<IA>
IEnumerable<IA> ieia = la;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
204 次 |
| 最近记录: |