首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >不可变值类型

不可变值类型
EN

Stack Overflow用户
提问于 2011-07-04 08:54:36
回答 3查看 1.2K关注 0票数 7

我正在阅读Eric关于突变只读结构的博客,我在这里看到了许多关于这个博客的引用,作为一个论点,为什么值类型必须是不可变的。但还有一件事还不清楚,即当您访问值类型时,您总是得到它的副本,下面是示例:

代码语言:javascript
复制
struct Mutable
{
    private int x;
    public int Mutate()
    {
        this.x = this.x + 1;
        return this.x;
    }
}

class Test
{
    public readonly Mutable m = new Mutable();
    static void Main(string[] args)
    {
        Test t = new Test();
        System.Console.WriteLine(t.m.Mutate());
        System.Console.WriteLine(t.m.Mutate());
        System.Console.WriteLine(t.m.Mutate());
    }
}

问题是,为什么当我改变

代码语言:javascript
复制
public readonly Mutable m = new Mutable();

代码语言:javascript
复制
public Mutable m = new Mutable();

一切都开始正常运转,这是人们所期待的。

请您解释一下为什么值类型必须是不可变的。我知道它对线程安全很好,但在这种情况下,同样可以应用于引用类型。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-07-04 09:40:29

具有变异方法的结构在几种情况下表现得很奇怪。

您已经发现的示例是一个只读字段。防御性复制是必要的,因为您不想修改只读字段。

但也被用作财产。再次发生隐式复制,并且只有副本发生变异。即使财产有一个策划人。

代码语言:javascript
复制
struct Mutable
{
    private int x;
    public int Mutate()
    {
        this.x = this.x + 1;
        return this.x;
    }
}

Mutable property{get;set;}

void Main()
{
    property=new Mutable();
    property.Mutate().Dump();//returns 1
    property.Mutate().Dump();//returns 1 :(
}

这表明变异方法在结构上是有问题的。但是,它并不表明具有setter的公共字段或属性的可变结构是有问题的。

票数 4
EN

Stack Overflow用户

发布于 2011-07-04 09:12:12

螺纹安全是一个明显的技术原因.它适用于值类型以及引用类型(参见System.String)。

更普遍的准则“值类型应该是不变的”是不同的。它是关于代码的可读性,主要来源于可变值可能造成的混乱。这个代码片段只是一个例子。大多数人不会期待1,1,1的结果。

票数 2
EN

Stack Overflow用户

发布于 2011-07-04 09:14:18

我不认识C#,所以我会试着回答你问题的第二部分。

为什么值类型必须是不可变的?

从领域驱动设计的角度来看,有两种类型的对象:

  • 值对象/类型-它们的标识是由它们的值决定的(例如,数字2总是2-数字2的恒等式总是相同的,所以2 == 2总是正确的)
  • 实体(引用类型)--它们可以由其他值类型组成,它们的身份是由它们的身份本身决定的(例如,人:即使有一个与你一模一样的人,也不会是你)

如果值类型是可变的,那么想象一下,如果更改数字2:2 == 1+1的值不被保证为真,会发生什么。

有关更多信息,请参见这些链接:

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

https://stackoverflow.com/questions/6569238

复制
相关文章

相似问题

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