简短的回答——C# 编译器和语言团队没有以这种方式实现它——他们要么没有想到(不太可能),要么认为这不是一个好主意......
repository.GetAll().Select(x=> new A { x.Stuff });
那是行不通的。你必须添加
这是一个对象初始化器。这通过在对象上调用默认构造函数,然后将属性名称与值匹配,即:Stuff = x.Foo
,并且实际上只是匹配属性的快捷方式,因此语法实际上只是“速记”:
A tmp = new A();
tmp.Stuff = x.Stuff;
现在,我想编译器团队可以假设等式上没有左侧的初始化语句应该搜索名称匹配且类型可隐式转换的匹配属性,但我怀疑这将落入“与坏主意列表调情“如果或何时由语言团队讨论。一般来说,C# 的语法相当明确,这会稍微放松一下,需要两个单独的匹配项(名称 + 类型),并且在许多情况下并不明显。由于您在此处使用公共 API ( A
),因此在任一侧进行重构 (A
或任何类型的 "x"
最后,这也不是必需的 - 如果您希望以这种方式构造 A 的实例,只需添加一个带有重载的构造函数(在任何情况下这在许多方面都更安全),然后使用:
repository.GetAll().Select(x=> new A(x.Stuff));
这使得意图和含义非常明确,并消除了脆弱的可维护性。
repository.GetAll().Select(x=> new { x.Stuff });
这是在做一些完全不同的事情——在这里,您正在初始化一个匿名类型,并让编译器为您完全确定类型名称和类型。我怀疑这被确定为“安全”,因为您从未真正使用过公共 API - 匿名类型不应该真正从定义它的方法中“泄漏”出来。在这种情况下,重构更改属性名称和有效更改值等的风险会大大降低并隔离到单个方法,这反过来又使这种“自动”命名功能总体上降低了风险。此外,这里没有一个简单的替代方案,因为您无法在匿名类型上定义构造函数,因此在这种情况下,没有一种简单的方法来获得简洁的语法。