我正在阅读Joseph Albahari的《C# 10入门指南》一书,它谈到了“匿名类型的无损突变”,但我甚至不知道突变是什么,在Google上我只能找到“突变测试”或“什么是无损突变?”这些内容总是作为记录类型的附带功能。请问有人可以给我解释一下吗?一些例子会更加感激!
我正在阅读Joseph Albahari的《C# 10入门指南》一书,它谈到了“匿名类型的无损突变”,但我甚至不知道突变是什么,在Google上我只能找到“突变测试”或“什么是无损突变?”这些内容总是作为记录类型的附带功能。请问有人可以给我解释一下吗?一些例子会更加感激!
突变(在“匿名类型的非破坏性突变”中使用的意义上)仅表示更改对象的状态。 这里是一个简单的例子:
var sb = new StringBuilder("Hello");
// We mutate the object referenced by sb, so that it contains
// "Hello!" rather than "Hello".
sb.Append("!")
Console.WriteLine(sb.ToString()); // prints Hello!
StringBuilder
是一个可变的类。其他类,例如 String
,是不可变的:
var s = "Hello";
// The following expression returns a *new* string "hello",
// but does not mutate the original string itself.
s.ToLower();
Console.WriteLine(s); // still prints Hello
那么,如果我们想要改变一个不可变类的内容,例如将字符串的内容转换为小写,我们会怎么做呢?我们创建一个新对象来包含修改后的版本。这就是string.ToLower
所做的事情:
var s1 = "Hello";
var s2 = s1.ToLower();
Console.WriteLine(s1); // prints Hello
Console.WriteLine(s2); // prints hello
s1
仍然存在,它并没有被销毁。另一方面,在第一个示例中的 sb.Append("!")
是“破坏性”的:包含没有感叹号的 Hello
的 sb
版本不再可访问。s = s.ToLower()
。但是,这并不改变 ToLower
创建新对象而不是就地修改旧对象的事实。 s = ...
确保变量 s
在之后指向新对象。)
var myObject = new { A = 1, B = 2 };
myObject.B = 3; // <- yields a compile-time error
var o1 = new { A = 1, B = 2 };
var o2 = o1 with { B = 3 };
// o1: A = 1, B = 2
// o2: A = 1, B = 3