如果我定义是一个结构中的C#使用自动性是这样的:

public struct Address
{
    public Address(string line1, string line2, string city, string state, string zip)
    {
        Line1 = line1;
        Line2 = line2;
        City = city;
        State = state;
        Zip = zip;
    }

    public string Line1 { get; protected set; }
    public string Line2 { get; protected set; }
    public string City { get; protected set; }
    public string State { get; protected set; }
    public string Zip { get; protected set; }
}

当我试图建立的文件,我得到一个编辑错误说 The 'this' object cannot be used before all of its fields are assigned to.这可以解决改变的构造,使一个链接电话到默认的构造是这样的:

public Address(string line1, string line2, string city, string state, string zip): this()
{
    Line1 = line1;
    Line2 = line2;
    City = city;
    State = state;
    Zip = zip;
}

我的问题是,为什么这项工作中,并发生了什么事?我猜猜,我试图证明它看IL,但我只是开玩笑,我自己如果我想我可以打破IL。但是我猜是自动性的工作,通过具有的编译器生成的领域为你的属性。这些领域无法通过访问代码,所有的设定和取得必须通过的特性。在创建一个结构,一个默认的构造不能明确定义。所以幕后,编译器必须产生一种默认的构造,将价值观的领域,开发人员不能看到。

任何和所有的IL向导的欢迎来证明或反驳我的理论。

有帮助吗?

解决方案

注意:从C#6开始,这不是必需的 - 但您应该使用C#6的只读自动实现的属性...

this()确保在编译器方面明确分配字段 - 它将所有字段设置为其默认值。在开始访问任何属性之前,您必须拥有一个完全构造的结构。

这很烦人,但就是这样。你确定你真的希望这是一个结构吗?为什么在结构上使用受保护的setter(不能从中派生出来)?

其他提示

一个酒店有什么比一封装的 Get 方法和/或 Set 法。CLR有的元数据,它表示,特定的方法应该被视为一个属性、意义的编纂者应该允许一些结构,这将不允许与方法。例如,如果 X 是一个读写酒店的 Foo, 一个编译器将翻译 Foo.X += 5Foo.SET_X_METHOD(Foo.GET_X_METHOD() + 5) (虽然该方法不同的名称,而不是通常可通过名)。

虽然autoproperty实现对get/set方法的其访问一个私人领域,在这样一种方式的行为或多或少像一个领域,从任何代码之外的财产,一个autoproperty是一对get/set方法,就像任何其他财产。因此,这样的声明 Foo.X = 5; 被翻译为 Foo.SET_X_METHOD(5).由于C#编译器只是认为,作为一种方法,呼叫,并且由于方法不包括任何元数据以表明哪些领域他们阅读或写,编译器将禁止的方法的呼吁,除非它知道每个现场的 Foo 已经编写的。

就个人而言,我的建议是避免使用autoproperties与结构类型。Autoproperties意义上课,因为这是可能的类属性,以支持功能,如更新的通知。即使早期版本的一类不支持更新的通知的,具有这些版本使用autoproperty而不是一场意味着,未来的版本可以加入更新的通知的功能,而不要求消费者的类重新设计。结构,但是,不能有意义地支持大多数类型的特点,人们可能希望添加到领域的性能。

另外,绩效之间的差异领域和特性要大得多大的结构比它与类型。事实上,很多的建议,以避免大型结构,是因为这种差异。大的结构实际上可以非常有效,如果一个可以避免复制的他们不必要的。即使一个已经一个巨大的结构 HexDecet<HexDecet<HexDecet<Integer>>>, ,哪里 HexDecet<T> 包含暴露的领域 F0..F15 的类型 T, 发言喜欢 Foo = MyThing.F3.F6.F9; 将只需要阅读一个的整数 MyThing 和储存它 Foo, 虽然 MyThing 将通过巨大的结构标准(4096整数占领16K).另外,一个可能的更新,这件很容易的,例如 MyThing.F3.F6.F9 += 26;.相比之下,如果 F0..F15 是自动性质,该声明 Foo = MyThing.F3.F6.F9 需要复制1K的数据 MyThing.F3 临时(称呼它 temp1, 然后64字节的数据 temp1.F6temp2),最后才得到读4个字节的数据 temp2.F9.Ick.更糟糕的是,在努力增加26的价值 MyThing.F3.F6.F9 将需要一些东西喜欢 var t1 = MyThing.F3; var t2 = t1.F6; t2.F9 += 26; t1.F6 = f2; MyThing.F3 = t1;.

许多长期投诉的关于"可变的结构类型"是真正的投诉有关的结构类型,具有读写性质。只是替代性的领域和问题消失。

PS:有时它可以是有用的,有一个结构,其属性访问的一类对象它拥有一个参考。例如,这将是很好有一个版本 ArraySegment<T> 类,它允许一个来说 Var foo[] = new int[100]; Var MyArrSeg = New ArraySegment<int>(foo, 25, 25); MyArrSeg[6] += 9;, 和最后一句添加到九元(25+6) foo.在旧版本的C#一个能做到这一点。不幸的是,经常使用的autoproperties在该框架中的领域将有更多的适当导致普遍的抱怨编译器,允许财产者被称为无益于只读结构;因此,呼吁任何财产定者在一个只读结构是现在被禁止的,是否或不属装定实际上将修改的任何领域的结构。如果人们根本没有制结构的可变通性制定者(作领域直接访问的时候可变性是适当的)编译器永远不会有实现这种限制。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top