最近,我一直在阅读大量有关值类型和引用类型及其差异的文献。这个问题围绕值类型的可变性和不可变性。
根据我所阅读的内容,.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原始类型,比如当不变性然而,可以混淆Int32
,Double
或者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命名空间中的Point,Size,Rectangle(以及其他一些)。
突然之间,我们被赋予了通过其属性对值类型进行变异的能力,我对为什么这样做是有理论的。以下面的代码为例
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);
但是,正如我所说的,我有一个关于为什么这些结构可变的理论:
所以最后我的问题是:
可变性不是值与引用类型之一。两者都有例子。以System.String
不可变类System.Drawing.Point
为例,以可变结构为例。
可变与不可变是基于类型用法的设计决策。是引用还是值类型是另一个不依赖于前者的设计决策。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句