C# 为什么不';匿名类型是否具有索引器属性?

C# 为什么不';匿名类型是否具有索引器属性?,c#,compilation,anonymous-types,C#,Compilation,Anonymous Types,既然匿名类型是由编译器生成的,为什么它们不进一步使用索引器访问其属性值(类似于ExpandoObject),但对其进行静态编码呢 一些背景: 我目前正试图在microORM中尽可能地提高最后一点性能,有一件事让我印象深刻:对匿名类型的反思 参数作为对象传入,虽然不需要匿名类型,但通常是。我必须使用反射来获取每个成员的名称和值,因为匿名类型实际上只是编译器生成的POCO 在使用C#中的ExpandoObject和其他一些动态结构之后,我发现自己缺少Expando的显式IDictionary接口实现

既然匿名类型是由编译器生成的,为什么它们不进一步使用索引器访问其属性值(类似于ExpandoObject),但对其进行静态编码呢

一些背景: 我目前正试图在microORM中尽可能地提高最后一点性能,有一件事让我印象深刻:对匿名类型的反思

参数作为对象传入,虽然不需要匿名类型,但通常是。我必须使用反射来获取每个成员的名称和值,因为匿名类型实际上只是编译器生成的POCO


在使用C#中的ExpandoObject和其他一些动态结构之后,我发现自己缺少Expando的显式IDictionary接口实现。

它们没有索引器,因为您将参数作为基本对象引用类型传入。如果您可以使用在接口上定义的方法,而该接口在方法契约中没有定义,这不是一个合理的假设

如果您查看,您将看到它实现了IDictionary和IDynamicMetaObjectProvider(让您的代码钩住DLR的神奇部分)。基本上,它带来了(Python中的字典可以通过基于字符串的“索引器”或使用.accessor访问,就好像它是直接在对象上定义的属性(甚至函数)一样)

匿名类型不是动态的。它们在编译时解析。不能在其定义中添加或减去


一般来说,反射API没有“dictionary”类型的访问权限,尽管我不明白为什么不能实现它。IDictionary是一个接口……您可以创建一个IDictionary实现,它接受一个对象,并使用该对象上的反射来解析索引器请求。

匿名类型有一个非常独特的用途,它与一些C#程序员希望它们做的事情没有多大关系。他们给林克供电,仅此而已。试图让他们做得更多是失败的。性能与此毫无关系。我很清楚,他们目前无法做到这一点,您对创建构造的最初原因是正确的,但我不同意在linq以外的任何地方使用匿名类型是“失败的鲸鱼”。他们现在是语言中非常重要的一部分。真正的失败之鲸是让匿名类型的成员只能“内部”访问。如果您在Razor:@Html.Partial(“~/Shared/DatePicker.cshtml”,new{id=“ctrl1”,mode=“yearonly”})中尝试此操作,它将失败并出现绑定错误,因为Razor引擎无法访问匿名类型的属性,即使使用@model dynamic声明模型也是如此。模型存在并且属性在调试器中可见,但是Razor实现的默认页面绑定器不会尝试通过反射访问属性。即使您传递一个ExpandooObject,它仍然会以类似的方式失败。是的,它们是作为object传递的,但是如果匿名类型实现了一个接口,那么执行“is”或“as”操作将起作用,从而暴露了contract.err,我想。正如汉斯在对原始问题的评论中所建议的那样,这不是你应该使用的东西。匿名类型是一个POCO对象,正如您所说,ExpandooObject是一个密封类,它实现IDictionary、ICollection、Enumerable、IEnumerable、INotifyPropertyChanged和IDynamicMetaObjectProvider。如果您需要这些ExpandoObjects,它将非常好,但是如果您不需要这些接口,那么您将为不需要的东西支付大量开销。如果需要,使用“is”或“as”检查ExpandooObject。