在回答这篇文章时,围绕一些小型结构,我意外地发现了以下情况:

使用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 / null / false。)

在C#中使用带有结构的自动属性时,这似乎是一个不幸的限制。从概念上思考,我想知道这是不是一个合理的地方,因为有一个允许在struct的构造函数中调用属性集访问器的异常,至少对于一个自动属性?

这是一个小问题,几乎是一个边缘案例,但我想知道其他人对此的看法......

有帮助吗?

解决方案

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


在C#6中,您需要调用默认构造函数才能使其工作:

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

这里一个更大的问题是你有一个可变的结构。这从不是一个好主意。我会成功的:

public int Size { get; private set; }

技术不可变,但足够接近。

使用最新版本的C#,您可以改进:

public int Size { get; }

现在只能<<>> 在构造函数中分配。

其他提示

您可以通过首先调用默认构造函数来解决此问题:

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

     public int Size { get; set; }
}

Tuple 类中发现了另一个模糊不清的问题。 >托管可扩展性框架(通过 Krzysztof Ko&#378; 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 的文档已更新为添加:

  

如果您在尝试时看到此错误   初始化结构中的属性   构造函数,解决方案是改变   要指定的构造函数参数   支持字段而不是   财产本身。 自动实现的   应避免使用属性   结构,因为他们没有支持   因此不可能   以任何方式初始化   构造

所以我认为这意味着当你遇到这个问题时,官方指导就是在你的结构中使用旧式属性,这可能不像其他两个探索的替代方案那样模糊(并且更易读)。远。

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