假设我有以下课程
public class Dog{}
public class Bulldog : Dog{}
public class Pitbull : Dog{}
我正在尝试创建这样的列表
var dogs2 = new[]
{
new { X = new Bulldog(), Y = 10},
new { X = new Pitbull(), Y = 20}
}.ToList();
但是,我收到以下错误
No best type found for implicitly - typed array
好吧,我想这很有道理。系统无法找出
X is a type of
Dog`所以,我尝试这样做
var dogs1 = Enumerable.Empty<object>()
.Select(x => new { X = new Dog (), Y = 0 })
.ToList();
dogs1.Add(new { X = new Pitbull(), Y = 10 });
dogs1.Add(new { X = new Bulldog(), Y = 10 });
现在,我收到此错误
cannot convert from '<anonymous type: PassingEvents.Bulldog X, int Y>' to '<anonymous type: PassingEvents.Dog X, int>'
。为什么不能转换? Bulldog
是否可强制转换为Dog
?有没有一种方法可以解决此问题,而不必创建新的类?下面的代码工作正常
public class DogCombo
{
public Dog X;
public int Y;
}
var dogs3 = new[]
{
new DogCombo{ X = new Bulldog(), Y = 10},
new DogCombo{ X = new Pitbull(), Y = 20}
}.ToList();
最佳答案
为什么不能转换?斗牛犬不是狗狗吗?
斗牛犬可以兑换成狗,是的。
您的推理如下:
斗牛犬可以兑换成狗
因此,带有Bulldog的匿名类型应该可以转换为带有Dog的匿名类型。
这种推理(即基础类型的属性应暗示转换后的类型的属性)被称为协方差。
在某些受限情况下,C#支持协方差。他们是:
牛头犬的阵列可以用作狗的阵列。请注意,这是不安全的协方差,因为您可以将贵宾犬放入数组的Dog中,但不能放入数组的Bulldog中。仅当您从不写入数组时,数组协方差才是安全的。IEnumerable<Bulldog>
可以转换为IEnumerable<Dog>
。这很安全。一系列的斗牛犬是一系列的狗。对于其他一些通用类型,例如IEnumerator<T>
,也是如此。
返回牛头犬的方法可以转换为返回狗的委托类型的委托。
在某些情况下,C#还支持相反性。例如,IComparable<Dog>
可能会转换为IComparable<Bulldog>
。可以比较狗的东西可以比斗牛犬。请注意,这种可转换性朝相反的方向发展,因此是相反的。
C#不支持类,结构或匿名类型的任何协方差(或相反)。
从理论上讲,C#可以根据需要支持匿名类型的矛盾。这样做是安全的。语言和运行时团队之前已经推荐了此功能。只是语言和运行时团队没有充分优先考虑该功能以实际实现它的情况。
如果您认为确实有充分的理由在匿名类型之类的结构类型上实现协变转换,则可以在Roslyn github论坛上对该主题进行讨论,也许有一天会实现。
有没有解决此问题的方法,而无需创建新类?
我建议您创建一个新类。但是,如果您想要一种便宜且简单的解决方法:只需将其显式转换为Dog
。
关于c# - 带有继承的匿名类型列表,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39860540/