是否使用一成不变的结构工作的公共只读字段? [英] Does using public readonly fields for immutable structs work?

查看:117
本文介绍了是否使用一成不变的结构工作的公共只读字段?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是声明不变的结构以适当的方式?

Is this a proper way to declare immutable structs?

public struct Pair
{
    public readonly int x;
    public readonly int y;

    // Constructor and stuff
}

我想不出为什么会碰到的问题,但我只是想问问,以确保。

I can't think of why this would run into problems, but I just wanted to ask to make sure.

在这个例子中,我使用整数。如果我使用的类来代替,但类也是不可变的,像这样?这应该工作也没关系吧?

In this example, I used ints. What if I used a class instead, but that class is also immutable, like so? That should work fine too, right?

public struct Pair
{
    public readonly (immutableClass) x;
    public readonly (immutableClass) y;

    // Constructor and stuff
}

(旁白:。据我所知,使用性能更加普及,并允许改变,但这种结构的目的是从字面上只是存储两个值,我在这里永恒的问题只是有兴趣)

(Aside: I understand that using Properties is more generalizable and allows changing, but this struct is intended literally to just store two values. I'm just interested in the immutability question here.)

推荐答案

如果您要使用结构,它是让他们一成不变的最佳做法。

If you're going to use structs, it is a best practice to make them immutable.

使所有字段只读是一个伟大的方式来帮助(1)文档的结构是不变的,和(2)prevent偶然的突变。

Making all the fields readonly is a great way to help (1) document that the struct is immutable, and (2) prevent accidental mutations.

然而,有一种皱纹,这实际上在一个奇怪的巧合,我打算在博客下周。那就是:只读在一个结构域是一个谎言。人们期望readonly字段无法改变,但当然可以。在结构领域的只读的声明写检查,在其账户没有钱。的一个结构没有自己的存储,它是存储能发生变异。

However, there is one wrinkle, which actually in a strange coincidence I was planning on blogging about next week. That is: readonly on a struct field is a lie. One expects that a readonly field cannot change, but of course it can. "readonly" on a struct field is the declaration writing cheques with no money in its account. A struct doesn't own its storage, and it is that storage which can mutate.

例如,让我们把你的结构:

For example, let's take your struct:

public struct Pair
{
    public readonly int x;
    public readonly int y;
    public Pair(int x, int y)
    {
        this.x = x;
        this.y = y;
    }
    public void M(ref Pair p)
    {
        int oldX = x;
        int oldY = y;
        // Something happens here
        Debug.Assert(x == oldX);
        Debug.Assert(y == oldY);
    }
}

有什么事情可以在有事在这里,导致调试断言被侵犯发生的呢?当然可以。

Is there anything that can happen at "something happens here" that causes the debug assertions to be violated? Sure.

    public void M(ref Pair p)
    {
        int oldX = this.x;
        int oldY = this.y;
        p = new Pair(0, 0);
        Debug.Assert(this.x == oldX);
        Debug.Assert(this.y == oldY);
    }
...
    Pair myPair = new Pair(10, 20);
    myPair.M(ref myPair);

而现在发生了什么?断言被违反! 这个和p指的是相同的存储位置。存储位置被突变,等等内容这个被突变,因为它们是同一件事。该结构是不是能够执行x和y的只读岬,因为结构不拥有存储;存储是一个局部变量,是免费的变异一样,因为它就是了。

And now what happens? The assertion is violated! "this" and "p" refer to the same storage location. The storage location is mutated, and so the contents of "this" are mutated because they are the same thing. The struct is not able to enforce the read-only-ness of x and y because the struct doesn't own the storage; the storage is a local variable that is free to mutate as much as it wants.

您不能的依赖的上不变,在一个结构只读域从未观察到变化;你可以依靠的唯一的事情是,你可以不写code,它直接改变它。但是,像这样有点偷偷摸摸的工作,你可以间接地改变这一切你想要的。

You cannot rely on the invariant that a readonly field in a struct is never observed to change; the only thing you can rely on is that you can't write code that directly changes it. But with a little sneaky work like this you can indirectly change it all you want.

又见这个问题上乔·达菲的优秀的博客文章:

See also Joe Duffy's excellent blog article on this issue:

<一个href=\"http://joeduffyblog.com/2010/07/01/when-is-a-readonly-field-not-readonly/\">http://joeduffyblog.com/2010/07/01/when-is-a-readonly-field-not-readonly/

这篇关于是否使用一成不变的结构工作的公共只读字段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆