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

发布于 2024-12-08 16:43:03 字数 347 浏览 5 评论 0原文

我有下一个代码:

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

    public int U { get; private set;  }
}

C# 编译器在指定行中给出了一对错误: 1) 在控制返回给调用者之前,必须完全分配自动实现的属性“TestConsoleApp.Program.TU”的支持字段。考虑从构造函数初始值设定项调用默认构造函数。 之前,不能使用“this”对象。

2) 在将“this”对象的所有字段分配给“我做错了什么?” 帮助我理解。

I have a next code:

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

    public int U { get; private set;  }
}

C# compiler give me a pair of errors in stated line:
1) Backing field for automatically implemented property 'TestConsoleApp.Program.T.U' must be fully assigned before control is returned to the caller. Consider calling the default constructor from a constructor initializer.
2) The 'this' object cannot be used before all of its fields are assigned to

What I do wrong? Help me understand.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

屋檐 2024-12-15 16:43:03

来自 C# 规范:

10.7.3 自动实现的属性

当属性被指定为自动实现的属性时,
隐藏的支持字段自动可用于该属性,
并且访问器被实现来读取和写入
支持字段。

[已删除]

因为后台字段不可访问,所以可以读写
只能通过属性访问器,即使在包含类型中也是如此。

[已删除]

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

所以你需要这个:

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

    public int U { get; private set; }
}

From the C# Specification:

10.7.3 Automatically implemented properties

When a property is specified as an automatically implemented property,
a hidden backing field is automatically available for the property,
and the accessors are implemented to read from and write to that
backing field.

[Deleted]

Because the backing field is inaccessible, it can be read and written
only through the property accessors, even within the containing type.

[Deleted]

This restriction also means that definite assignment of struct types
with auto-implemented properties can only be achieved using the
standard constructor of the struct, since assigning to the property
itself requires the struct to be definitely assigned. This means that
user-defined constructors must call the default constructor.

So you need this:

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

    public int U { get; private set; }
}
千笙结 2024-12-15 16:43:03

好吧,首先您要创建一个可变结构 - 这几乎总是一个非常糟糕的主意。可变结构有时会以您意想不到的方式运行。好吧,它只是私有可变的,但是您编写了代码来改变它的事实是一个坏兆头。

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

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

编译器要求任何构造函数都明确分配所有字段(这就是为什么您之前收到 first 错误;编译器不“知道”该属性为字段分配了值) - 通过链接到 this() ,您要确保在到达构造函数时body 中,所有字段已经都已明确分配,您无需再担心。

但是,除非您实际上想要允许突变,我建议您将其设为真正的只读属性:

struct T 
{
    private readonly int u;

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

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

现在更明显表明您不想对其进行突变甚至在结构本身内

Well, for a start you're creating a mutable struct - that's almost always a really bad idea. Mutable structs can sometimes behave in ways you don't expect. Okay, it's only privately mutable, but the fact that you've written code to mutate it is a bad sign.

The reason for the second error is that you can't use any properties or methods of the struct until all fields have been assigned, so you need to chain to the implicit parameterless constructor:

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

The compiler requires that any constructor leaves all the fields definitely assigned (which is why you were getting the first error before; the compiler doesn't "know" that the property assigns the field a value) - by chaining to this(), you're making sure that by the time you get to your constructor body, all the fields are already definitely assigned, and you don't need to worry about it any more.

However, unless you actually want to allow mutation, I suggest you just make it a genuinely read-only property:

struct T 
{
    private readonly int u;

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

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

Now it's more obvious that you don't want to mutate it even within the struct itself.

月野兔 2024-12-15 16:43:03

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

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

Add a call to the default constructor:

public T(int u) : this() 
{
    this.U = 10;
}
执妄 2024-12-15 16:43:03

你必须在这里使用默认构造函数:

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

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


}

you have to use the default constructor here:

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

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


}
又爬满兰若 2024-12-15 16:43:03

从 C# 6 开始,这不再是问题,并且可以正确编译。请查看此处

From C# 6 this is not an issue anymore and it compiles correctly. Look here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文