首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >类的属性是否从任何地方都是不可改变的,以便它在C#中是不可变的?

类的属性是否从任何地方都是不可改变的,以便它在C#中是不可变的?
EN

Stack Overflow用户
提问于 2016-06-19 09:10:10
回答 2查看 72关注 0票数 0

考虑一下这门课:

代码语言:javascript
代码运行次数:0
运行
复制
public class Point
{
    private int x { get; private set; }
    private int y { get; private set; }

    public Point(int x, int y)
    {
        this.x = x;
        this.y = y;
    }

    public void ChangePoint(int x, int y)
    {
        this.x = x;
        this.y = y;
    }
}

这个类被认为是不可变的吗?换句话说,如果一个类是不可变的,那么它的属性是在任何地方都是不可改变的,还是只在类之外?

谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-06-19 09:15:42

您可以说,基于以下类创建的对象是immutable,因为没有任何方法更改x and y。它们只设置在对象的构造中。

代码语言:javascript
代码运行次数:0
运行
复制
class Point
{
    public int X { get; private set; }
    public int Y { get; private set; }

    public Point(int x, int y)
    {
        X = x;
        Y = y;
    }
}

尽管如此,以下声明如下:

代码语言:javascript
代码运行次数:0
运行
复制
var point = new Point(3,4);

创建一个行为像不可变对象的对象。我们必须指出,C#没有固有的不可变的数据结构。不可变的数据结构在LISP、Haskell等功能语言中很常见。

是的,但是我的类是否称为不可变,因为它们不是仅在构造函数中设置的?

不,如果添加方法ChangePoint,则不能讨论不可变的数据结构。因为您修改了所创建的对象,所以您更改了它的状态。

理解不变性概念的一个更好的方法是:

代码语言:javascript
代码运行次数:0
运行
复制
var numbers = new List<int>();
numbers.Add(1);
numbers.Add(2);

创建一个列表,然后添加1和2。这样,每次添加新项时,都会更改相同列表的状态。(出于简化的原因,我们没有考虑到列表已经满足其容量的情况,并且应该创建另一个双大小数组,在那里复制元素并添加新项。)

另一方面,假设在Haskel中有以下列表:

代码语言:javascript
代码运行次数:0
运行
复制
[1,2,3]

然后当您将添加另一个元素时

代码语言:javascript
代码运行次数:0
运行
复制
[1,2,3]++[4]

将创建并返回一个新列表,即1、2、3、4。每次向列表中添加一个新项时,都会创建一个新对象,该对象包含初始列表的元素和新添加的元素。

但是,有一个库为您提供了在C#中使用不可变集合的机会。

票数 1
EN

Stack Overflow用户

发布于 2016-06-19 09:13:52

实际上,由于C#没有除不变集合以外的不可变类型,所以我将应用以下规则:

引用类型是可变的,除非它的所有属性都不会超过对象的构造时间,并且它的数据公开为只读属性或字段,或者常量

...or:

引用类型是不可变的,除非其属性或字段可以在构造时间之后更改。

顺便说一句,不变集合遵循上述规则:不变性不是使用C#语法强制执行的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37905621

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档