难以理解不可变结构的正确实现

本文关键字:实现 结构 不可变 | 更新日期: 2023-09-27 18:27:57

我认为这很简单,但由于某种原因,我找不到任何关于可变结构和不可变结构之间区别的明确例子。我读过我创建的任何结构都应该是不可变的,以防止将来在使用中出现任何混淆。回顾我一直在做的事情,我似乎创建了一个可变结构:

    public struct Connection 
    {
        public int x, y;
        public float strength; 
        public Connection(int x, int y, float strength)
        {
            this.x = x;
            this.y = y;
            this.strength = strength;
        }
    }

根据我所读到的,要使我的结构不可变,它应该如下:

    public struct Connection 
    {
        public readonly int x, y;
        public readonly float strength; 
        public Connection(int x, int y, float strength)
        {
            this.x = x;
            this.y = y;
            this.strength = strength;
        }
    }

然而,当我阅读dotnetperls时,我感到困惑,根据我所读的内容,那里使用的例子似乎是可变的。

抱歉,这是个新手问题。非常感谢您的帮助。

难以理解不可变结构的正确实现

使用不可变结构,所有实例字段/属性都标记为只读。你是对的:问题中的第一个例子是可变的,而第二个例子是不可变的。

不可变结构在处理异步/多线程代码时提供了许多优点,但顾名思义,它们的值不能更改。对于structs来说,这往往不是一个大问题,但如果将相同的方法应用于通过引用传递的类,则可能会出现问题。

有两种主要情况适合使用结构:(1)希望用胶带将一堆变量粘在一起;(2) 人们想要一个不可变的小对象。如果不看你的类型是如何使用的,我就无法判断哪种情况适用。

如果一个类型的目的是表现得像一堆用胶带粘在一起的变量,那么前一个声明在这方面是完美的,因为任何了解.NET中结构类型的人都可以立即看到它,并知道它代表一堆用管道胶带粘在一起的变量,并且除了封装字段的名称和类型之外,其行为将与任何其他此类类型完全相同。

如果希望类型表现得像一个不可变对象,那么实现这一点的最简单方法可能是将字段声明为只读。请注意,这样做实际上不会使结构不可变,因为不存在不可变结构。如果某个地方存在两个定义为Connection c1, c2;的字段,则语句c1=c2;将通过用c2的相应字段的值覆盖其所有字段(public和private)来对c1进行变异。.NET框架将只检查Connection类型以确定所有字段的总大小;它不会关心"只读"声明或任何其他可能试图对字段进行的保护。