Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 无法分配结构中自动实现的属性_C#_.net_Constructor_Automatic Properties - Fatal编程技术网

C# 无法分配结构中自动实现的属性

C# 无法分配结构中自动实现的属性,c#,.net,constructor,automatic-properties,C#,.net,Constructor,Automatic Properties,我有下一个代码: struct T { public T(int u) { this.U = 10; //Errors are here } public int U { get; private set; } } C#编译器在指定行中给我一对错误: 1) 在将控件返回给调用方之前,必须完全分配自动实现的属性“TestConsoleApp.Program.T.U”的支持字段。考虑从构造函数初始化器调用默认构造函数。 2) 在将“this

我有下一个代码:

struct T 
{
    public T(int u) 
    { 
        this.U = 10; //Errors are here
    }

    public int U { get; private set;  }
}
C#编译器在指定行中给我一对错误: 1) 在将控件返回给调用方之前,必须完全分配自动实现的属性“TestConsoleApp.Program.T.U”的支持字段。考虑从构造函数初始化器调用默认构造函数。 2) 在将“this”对象的所有字段指定给之前,不能使用该对象


我做错了什么?帮助我理解。

添加对默认构造函数的调用:

public T(int u) : this() 
{
    this.U = 10;
}
public T(int u) : this()
{ 
    this.U = 10;
}

首先,你要创建一个可变结构——这几乎总是一个非常糟糕的主意。可变结构有时会以您意想不到的方式运行。好吧,它只是私下可变的,但事实上,您编写代码来对其进行变异是一个坏迹象

第二个错误的原因是,在分配所有字段之前,无法使用结构的任何属性或方法,因此需要链接到隐式无参数构造函数:

public T(int u) : this() 
{
    this.U = 10;
}
public T(int u) : this()
{ 
    this.U = 10;
}
编译器要求任何构造函数都保留所有明确指定的字段(这就是为什么您之前遇到第一个错误;编译器不“知道”属性为字段指定了值)-通过链接到
this()
,您可以确保在到达构造函数主体时,所有字段都已明确分配,您无需再担心

但是,除非您确实希望允许突变,否则我建议您将其设置为真正的只读属性:

struct T 
{
    private readonly int u;

    public T(int u)
    { 
        this.u = 10;
    }

    public int U { get { return u; } }
}

现在更明显的是,即使在结构本身中,您也不希望对其进行变异。

您必须在此处使用默认构造函数:

struct T
{
    public int U { get; private set; }

    public T(int u) : this()
    {
        U = 10;
    }


}
根据C#规范:

10.7.3自动实现的属性

将属性指定为自动实现的属性时, 隐藏的备份字段将自动用于属性, 访问器被实现为读写它 后场

[已删除]

由于备份字段不可访问,因此可以对其进行读写 仅通过属性访问器,即使在包含类型内也是如此

[已删除]

这个限制还意味着结构类型的确定赋值 对于自动实现的属性,只能使用 结构的标准构造函数,因为指定给属性 它本身要求明确指定结构。这意味着 用户定义的构造函数必须调用默认构造函数

所以你需要这个:

struct T 
{
    public T(int u)
        : this()
    { 
        this.U = u;
    }

    public int U { get; private set; }
}

从C#6开始,这不再是一个问题,它可以正确编译。看

是的,这些细节很宝贵。我现在都知道了。谢谢。从C#6开始,您不需要添加
:this()
所有我想做的事情您称之为“糟糕的设计”:(有什么规则吗?@Praetor12:你可以阅读类库开发人员的设计指南:-其中包括一些内容,但不是全部。值得找一些阅读材料来充实你的知识,我的前两个建议是Cwalina和Abrams的“框架设计指南:可重用.NET库的约定、习惯用法和模式”,以及Skeet先生自己的“C#Depth”“。了解框架最佳实践需要经验,当您开始了解的不仅仅是您的代码的功能,还包括它对代码其他部分的影响时,您将开始自然地改进您编写代码的方式,并希望在可能的情况下开始使用最佳实践。”。