繁体   English   中英

在 C# 中,值类型是可变的还是不可变的?

[英]In C# , Are Value types mutable or immutable ?

值类型行为表明,我们持有的任何值都不能通过其他变量来改变。

但是我仍然对我在这篇文章的标题中提到的内容感到困惑。 谁能澄清一下?

值类型可以是可变的(以一些奇怪的边缘情况为模)不可变的,这取决于您如何编写它们。

可变:

public struct MutableValueType
{
    public int MyInt { get; set; }
}

不可变:

public struct ImmutableValueType
{
    private readonly int myInt;
    public ImmutableValueType(int i) { this.myInt = i; }

    public int MyInt { get { return this.myInt; } }
}

内置值类型( intdouble等)不可变的,但您可以非常轻松地创建自己的可变struct

一条建议:不要 可变值类型是个坏主意,应该避免。 例如,这段代码做了什么:

SomeType t = new SomeType();
t.X = 5;

SomeType u = t;
t.X = 10;

Console.WriteLine(u.X);

这取决于. 如果SomeType是一个值类型,它会打印5 ,这是一个非常令人困惑的结果。

有关为什么应避免使用可变值类型的更多信息,请参阅此问题

所有原始值类型,如 int、double、float 都是不可变的。但结构本身是可变的。所以你必须采取措施使它们成为不可变的,因为它会造成很多混乱。

任何包含任何信息的值类型实例都可以被可以写入包含它的存储位置的代码改变,并且任何值类型实例都不能被不能写入包含它的存储位置的代码改变。 这些特性使得可变值类型的私有存储位置在许多情况下成为理想的数据容器,因为它们结合了来自可变性的更新便利性和来自不可变性的控制。 请注意,可以为值类型编写代码,这样就不可能在没有首先包含所需数据的实例(可能是新创建的临时实例)的情况下改变现有实例,并覆盖前一个实例具有后者的内容,但这不会使值类型或多或少地可变,而不是缺少这种能力。 在许多情况下,它只会使突变变得尴尬,并使它看起来像这样的陈述:

  MyKeyValuePair =
    new KeyValuePair<long,long>(MyKeyValuePair.Key+1, MyKeyValuePair.Value+1>;

将创建一个新实例,但不影响现有实例。 如果KeyValuePair是不可变的 class,并且一个线程正在执行MyKeyValuePair.ToString()而另一个线程正在执行上述代码,则ToString调用将作用于旧实例或新实例,因此会产生两个旧值或两者新的价值观。 然而,由于KeyValuePair是一个结构体,上述语句将创建一个新实例,但它不会使MyKeyValuePair引用新实例——它只会将新实例用作模板,其字段将被复制到MyKeyValuePair 如果KeyValuePair是一个可变结构,则上述代码可能预期含义的最自然表达将更像是:

  MyKeyValuePair.Key += 1;
  MyKeyValuePair.Value += 1;

也许:

  var temp = MyKeyValuePair;
  MyKeyValuePair.Key = temp.Key+1;
  MyKeyValuePair.Value = temp.Value+1;

并且线程的含义会更加清晰。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM