.NET中的值类型,不可变性(良好)和可变性(邪恶)

马修·莱顿

最近,我一直在阅读大量有关值类型和引用类型及其差异的文献。这个问题围绕值类型可变性不可变性

根据我所阅读的内容,.NET中的值类型似乎应该以不可变的方式编写。也就是说,一旦为它们分配了值,则该类型的值在内存中就不会更改。只有该类型的后续副本才能在内存中构造具有基于原始值的新值的新实例。.NET中的可变性似乎是邪恶的。

为了阐明对不变性的理解(为了我自己和他人),我在下面演示了这一点:

DateTime并且TimeSpan不可变结构的示例,因为一旦将值分配给实例,该实例值就无法更改,这可以通过只读属性来证明:

DateTime dt = new DateTime();
DateTime newdt = dt.AddDays(2); // Okay, new value stored in newdt
newdt.Year = 1945; // Error, cannot write to readonly property

寻找AR原始类型,比如当不变性然而,可以混淆Int32Double或者Char,因为类型似乎是可变的,但我的直觉是,实际上,不变性是透明通过CLR处理; 以下面的操作为例(我已经在一些非常基本的x86中进行了评论,以了解如何根据原始类型处理不变性

int x = 0;

// xor eax, eax;     'clear register to 0
// push eax;         'push eax (0) onto the stack

x = 5;

// pop eax;          'pop stack (0) into eax
// mov eax, 5;       'eax = 5
// push eax;         'push eax (5) onto the stack

x++;

// pop eax;          'pop stack (5) into eax
// add eax, 1;       'eax = 5 + 1
// push eax;         'push eax (6) onto the stack

到目前为止一切顺利 微软似乎在将不变性实现为其价值类型方面做得很好。但是随后我们开始发现坏苹果,以及使可变性看起来不错的细微差别,并使开发人员产生错误的安全感!

我说的System.Drawing命名空间中的PointSizeRectangle(以及其他一些)

突然之间,我们被赋予了通过其属性对值类型进行变异的能力,我对为什么这样做是有理论的。以下面的代码为例

Point p = new Point();
p.X = 100;
p.Y = 200;

// Immutability (had it been implemented here) might infer the following usage

Point p = new Point(100, 200);
Point p2 = p.AddXY(200, 300);

但是,正如我所说的,我有一个关于为什么这些结构可变的理论:

  1. Microsoft只是想使使用这些结构更容易。
  2. 它们可与本地GDI / GDI +调用互操作,因此它们的行为是围绕其本地C / C ++对应对象设计的。

所以最后我的问题是:

  1. 我是否已完全涵盖并理解不变性和可变性?
  2. 开发人员是否应该通常将目标定为构建不变的结构?
  3. 什么时候可以构建可变结构?
敦促

可变性不是值与引用类型之一。两者都有例子。System.String不可变类System.Drawing.Point为例,以可变结构为例。

可变与不可变是基于类型用法的设计决策。是引用还是值类型是另一个不依赖于前者的设计决策。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

字符串不可变性允许哈希码值被缓存

来自分类Dev

使用jbcrypt时的可变性能和降级性能

来自分类Dev

字符串不可变性的困惑

来自分类Dev

Java中getter和setter的日期可变性

来自分类Dev

const和操作可变性对C#性能的影响

来自分类Dev

简单的Ruby变量可变性

来自分类Dev

Nim:参数和可变性的地址

来自分类Dev

Scala函数式编程和可变性

来自分类Dev

Swift中的数组可变性

来自分类Dev

Python OOP实例和类的可变性

来自分类Dev

Swift协议的可变性

来自分类Dev

TypeScript-Readonly <T>的可变性和反转

来自分类Dev

用于可变性的Json Schema模板

来自分类Dev

使用内部可变性模式的“ BorrowMutError”

来自分类Dev

关于引用的可变性和引用所引用的值的可变性有些困惑

来自分类Dev

Scala函数式编程和可变性

来自分类Dev

字符串不可变性允许哈希码值被缓存

来自分类Dev

Java字符串不可变性和使用相同的字符串值创建新的字符串

来自分类Dev

Java中getter和setter的日期可变性

来自分类Dev

Swift中的可变性

来自分类Dev

可变性混乱

来自分类Dev

实例属性可变性(非常基础)

来自分类Dev

简单的Ruby变量可变性

来自分类Dev

Swift中的数组可变性附加

来自分类Dev

通过对象引用和可变性

来自分类Dev

python中列表的可变性

来自分类Dev

this.key与可变性能

来自分类Dev

导入变量的可变性

来自分类Dev

在python中测试可变性