假设我有以下课程
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();
可投弃?{/ p>
有没有办法解决这个问题,而不必为新课程创作?下面的代码工作得很好
let appState = mobx.observable({
todos: [ 'yellow', 'blue', 'red' ]
})
appState.addTodo = function() {
appState.todos.push( 'new one' )
}
答案 0 :(得分:8)
您可以将X显式地转换为Dog
:
var dogs2 = new[]
{
new { X = (Dog)new Bulldog(), Y = 10},
new { X = (Dog)new Pitbull(), Y = 20}
}.ToList();
答案 1 :(得分:8)
为什么不能转换?不是斗牛犬可以施加给狗吗?
斗牛犬可转换为狗,是的。
您的推理如下:
这种推理 - 底层类型的属性应该意味着转换下类型的属性 - 称为协方差。
C#支持某些受限情况下的协方差。他们是:
Bulldog数组可用作Dog的数组。请注意,这是 unsafe covariance ,因为您可以将Poodle放入Dog数组中,但不能放入Bulldog数组中。只有从不写入数组时,数组协方差才是安全的。
IEnumerable<Bulldog>
可能会转换为IEnumerable<Dog>
。这很安全。一系列斗牛犬是一系列狗。对于其他一些通用类型也是如此,例如IEnumerator<T>
。
返回Bulldog的方法可以转换为返回Dog的委托类型的委托。
在某些情况下,C#还支持逆转。例如,IComparable<Dog>
可能会转换为IComparable<Bulldog>
。可以比较狗的东西可以比较斗牛犬。请注意,此可兑换性的方向相反,因此 contra 变体。
C#不支持类,结构或匿名类型的任何协方差(或逆变)。
理论上,C#可以根据需要支持匿名类型的逆变;这样做是安全的。之前语言和运行时团队已经投入了这个功能。简单来说,语言和运行时团队没有对该功能进行高度优先级的实际实现。
如果您认为有充分理由在匿名类型等结构类型上实现协变转换,您可以在Roslyn github论坛上开始讨论该主题,也许有一天它会实现。
有没有办法解决这个问题,而无需创建新类?
我建议您创建一个新类。但是,如果您想要一种便宜且简单的解决方法:只需将明确转换为Dog
。