为什么你不能将字段和属性声明为具有匿名类型?

时间:2017-02-23 14:05:29

标签: c# .net mono anonymous-types anonymous-class

我在完成工作时遇到了一个问题,即将软件从Flash AS3移植到.NET / Mono。在AS3代码库中,我可以找到许多Object声明,这些声明初始化如下:

private const MAPPING:Object =
{
    ssdungf:'flydung',
    ssdungt:'flydung',
    superfutter:'superfeed'
}

对我来说最好的选择是在C#中使用匿名类型:

var MAPPING = new
{
    ssdungf = "flydung",
    ssdungt = "flydung",
    superfutter = "superfeed"
};

问题是......让我引用MSDN(source):

  

您不能将方法的字段,属性,事件或返回类型声明为具有匿名类型

但他们不会说出原因。

所以问题仍然存在:为什么你不能将字段和属性声明为具有匿名类型?为什么.NET创建者会从该选项中删除它?

我从这里得到警告,我的问题似乎是主观的,但我认为根本不存在 - 需要有客观的理由。

至于我,我没有看到任何障碍,但不知何故它不受支持。因为编译器可以很容易地为类的字段或属性生成类型,就像它对局部变量一样。

我的选择是使用dynamic类型但不幸的是我正在使用的Mono引擎被剥离了。

我的选择是使用对象类型并使用以后的反射来查找这些字段:

 private static readonly object MAPPING = new
 {
     ssdungf = "flydung",
     ssdungt = "flydung",
     superfutter = "superfeed"
 };

但是使用反射就是这种情况我会说很脏。

我试图找到答案,但我真的没找到答案。以下是对类似问题的一些回答,但他们没有回答原因:

Can a class property/field be of anonymous type in C# 4.0?

Declaring a LIST variable of an anonymous type in C#

How do you declare a Func with an anonymous return type?

2 个答案:

答案 0 :(得分:1)

  

为什么你不能将字段和属性声明为具有匿名类型?

因为C#是静态类型的,所以任何内存位置都必须给出一个类型,声明就这样做了。对于本地人,我们可以从上下文推断它是否与var声明同时初始化,但这是即使类型没有名称也可用的类型的简写。

具有匿名类型的字段,即静态绑定但难以描述的类型,意味着什么?

dynamic确实是与您移植的代码最接近的类比,但由于您无法使用,您可以考虑使用IDictionary<string, object>(顺便提一下{{1} },通常与ExpandoObject一起使用,使对象的行为更像javascrpt对象,在幕后工作)。与为所需对象创建类但可以工作的情况相比,这将更慢且更不类型安全。

答案 1 :(得分:0)

anoynmous属性的问题是:你如何获得/设置它?

假设它可行:

class MyClass
{
    public MyField = new { TheValue = "Hello World" };
}

现在在您的消费代码中,您将编写代码来阅读代码:

MyClass m = new MyClass();
m.MyField.TheValue = "newValue";

这与MyField的类型有什么不同?你得到的只是你可以省略两到三行代码而什么也得不到。但我认为你可能会产生许多问题,因为没有人知道他可以分配给该成员/期望什么。

此外,您无法对匿名对象做多少工作,基本上您只需设置并阅读即可。您可以调用的方法(EqualsGetHashCode继承自object除外),因此机会非常低。

最后但并非最不重要的是,匿名对象通常用作临时对象,例如在Select语句中。当你使用它时,你会说:这种类型只能在当前特定范围内使用,并且可以作为内部实现细节被整个世界忽略。创建匿名类型的属性会将这样的细节暴露给外部。当然你可以说设计师至少可以让他们成为private成员,但我想这样做会绕过完整的可访问性概念。