2009-01-07 71 views
61

周围的一些小的结构踢在回答this post,我遇到了意外以下内容:自动属性和结构不要混合?

以下结构,使用一个int字段是完全合法的:

struct MyStruct 
{ 
    public MyStruct (int size) 
    { 
     this.Size = size; // <-- Legal assignment. 
    } 

    public int Size; 
} 

但是,下面的结构,使用自动属性不会编译:

struct MyStruct 
{ 
    public MyStruct (int size) 
    { 
     this.Size = size; // <-- Compile-Time Error! 
    } 

    public int Size{get; set;} 
} 

返回的错误是“不能使用‘这个’对象之前所有字段被分配到”。我知道这是一个结构的标准过程:任何属性的后台字段必须从结构的构造函数中直接分配(而不是通过属性的set访问器)。

一种解决方法是使用一个明确的支持领域:

struct MyStruct 
{ 
    public MyStruct(int size) 
    { 
     _size = size; 
    } 

    private int _size; 

    public int Size 
    { 
     get { return _size; } 
     set { _size = value; } 
    } 
} 

(请注意,VB.NET不会有这个问题,因为在VB.NET所有领域都将自动初始化为0 /空/假时第一个创建。)

这似乎是一个不幸的限制时,使用C#中的结构自动属性。从概念上思考,我在想,如果这不是一个合理的地方,那么允许在结构的构造函数中调用属性集访问器的异常,至少对于自动属性来说呢?

这是一个小问题,几乎是一个边缘的情况下,但我不知道别人怎么想这个...

+2

C#中的字段也被初始化为0/null/false。记住它的运行时间,而不是特定的语言。 ;) – 2009-02-11 06:00:37

+0

不适用于C#中结构体的字段。对于一个结构体来说,如果使用隐式的,无参数的构造函数,这些字段必须由显式构造函数或调用者初始化。 VB.NET没有这个限制,因此,上面那个不能用C#编译的例子会在VB.NET中编译和运行得很好。 – 2011-03-26 02:08:17

+0

可能的重复[为什么有必要调用:this()在结构上使用c#自动属性?](http://stackoverflow.com/questions/272153/why-is-it-necessary-to-call -this-on-a-struct-to-use-automatic-properties-in-c) – nawfal 2013-06-03 17:59:50

回答

80

从C#6起:这不再是一个问题


Becore C#6,你需要调用默认的构造函数这个工作:

public MyStruct(int size) : this() 
{ 
    Size = size; 
} 

这里的一个更大的问题是,你有一个可变的结构。这是从来没有一个好主意。我想使它:

public int Size { get; private set; } 

技术上一成不变的,但足够接近。

随着最新版本的C#,可以改善这一点:

public int Size { get; } 

这可现在可以在构造函数中分配。

10

您可以通过先调用默认的构造函数解决这个问题:

struct MyStruct 
{ 
    public MyStruct(int size) : this() 
    { 
     this.Size = size; // <-- now works 
    } 

    public int Size { get; set; } 
} 
7

另一个不起眼的工作,围绕这个问题是一个临时Tuple类看准Managed Extensibility Framework(通过Krzysztof Koźmic):

public struct TempTuple<TFirst, TSecond> 
{ 
    public TempTuple(TFirst first, TSecond second) 
    { 
     this = new TempTuple<TFirst, TSecond>(); // Kung fu! 
     this.First = first; 
     this.Second = second; 
    } 

    public TFirst First { get; private set; } 
    public TSecond Second { get; private set; } 

(来自Codeplex的完整源代码:Tuple.cs

我还注意到文档塔季翁为CS0188已更新,增加了:

如果你想 时看到这个错误在一个结构 构造函数初始化属性,解决的办法就是改变 构造函数参数指定 而不是支持字段属性本身。 自动执行 属性应该避免在 结构中,因为它们没有后盾 字段,因此不能以 构造函数初始化 。

所以我认为这意味着,官方指导是在你的结构,当你运行到这个问题,这可能是不太隐晦(多readible)比任何其他的使用旧式性质到目前为止已探索两种替代方案