当前位置: 首页 > 编程语言 > C#

协变对象初始化器?分享

时间:2023-04-10 18:17:19 C#

协变对象初始值设定项?假设我有一个带有字典属性的类,使用对象初始值设定项我可以使用这种语法(对我来说似乎很干净):newMyClass(){Table={{"test",true},{"test",false}}}但是,在初始化程序之外我不能这样做:this.Table={{"test",true},{"test",false}};为什么初始化程序是一个特例?我猜它与LINQ要求、协方差或类似的东西有关,但在任何地方使用这种初始化程序感觉有点不一致......这个问题有点令人困惑,因为这个问题与LINQ,它与泛型变体无关,并且有集合初始化器和对象初始化器。据我所知,真正的问题是,“为什么在对象创建表达式之外使用集合初始值设定项是非法的?”这里的相关设计原则是,一般来说,我们希望创建和初始化对象的操作包含在“新建”一词中,作为向读者发出的信号,表明对象创建正在此处进行。(是的,在C#中这条规则有一些例外。作为读者的练习,看看你是否能说出所有的名字。)按照你自己的方式做事会使代码更难理解。快点,这是干嘛的?d=新列表(){10,20,30};d={40,50,60};第二行是否将40、50、60附加到现有列表?还是用新列表替换旧列表?那里没有“新”,读者是否期望创建一个新对象?当你说q=newWhatever(){MyList={40,50,60}};这不会创建新列表;它将40,50,60附加到构造函数分配的现有列表中。因此,您建议的语法不明确并且确实创建了一个新列表。提议的功能既令人困惑又不必要,因此不太可能很快实施。此限制早于LINQ很长一段时间。即使回到C中,您也可以编写intnumbers[5]={1,2,3,4,5};但是你不能使用这种语法给数组赋值。我猜C#背后的原因是通常你不应该对两个不同的对象使用相同的引用。如果您需要为现有引用分配一个新集合,很可能是您的代码设计不当,您可以通过定义初始化集合,或者使用两个单独的引用而不是一个。考虑您的语法在运行时抛出NullReferenceException-您确定可以使用它吗?publicclassTest{公共词典表{get;设置;}}publicvoidTestMethod(){Testt=newTest{Table={{"test",false}}};//NullReferenceException}这将编译为以下内容(通过反射器):Testg__initLocal3=newTest();g__initLocal3.Table.Add("测试",0.0M);如您所见,Table未初始化,因此在运行时产生NullReferenceException。如果您在Test的构造函数中创建Dictionary,则类初始化器会生成一系列Add语句,这些语句是初始化器中的语法糖(对于IEnumerable)。由于我们无法看到或想象的不可预见的副作用,这可能不是由正常代码引入的。EricLippert可能会提供帮助,因为他可能对手头的问题有更多的了解。以上就是C#学习教程:协变对象初始化器?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: