What is mutation in C#?
Asked Answered
R

1

6

I am reading Joseph Albahari's book "C# 10 in a Nutshell", it talks about "Nondesctructive mutation for anonymous types" but I don't even know what mutation is, on google all I could find was "Mutation testing" or "What is Nondesctructive mutation?" which they always end up in as a side feature to record type. Could someone please break it down to me? Some examples would be much appreciated!

Rondarondeau answered 20/8, 2022 at 20:35 Comment(4)
In this case, "to mutate" just means "to change the state of an object". Do you already understand the difference between mutable and immutable objects? "Nondestructive mutation" is a technique to do something similar to mutation with immutable types.Pantechnicon
stevefenton.co.uk/2020/05/csharp-9-non-destructive-mutationNeoclassicism
@Pantechnicon so mutation is related to mutability? So, the mutation test is basically "testing if the type of the object is changed" or is it "the value of an object is changed"?Rondarondeau
No, "mutation testing" is something completely different. Mutation testing is called mutation testing because it's about mutating (= changing) code. "Nondestructive mutation for anonymous types" is about mutating (= changing) objects. In genetics (to give a completely unrelated third example), "mutation" refers to changes in the genome. That's the beauty of the English language: Words are meaningless without context.Pantechnicon
P
11

To mutate (in the sense used in "nondesctructive mutation for anonymous types") just means to change the state of an object. Here is a simple example:

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 is a mutable class. Other classes, such as String, are immutable:

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

So, what do we do if we want to mutate the contents of an immutable class, for example, to lowercase the contents of a string? We create a new object that contains the modified version. This is what string.ToLower does:

var s1 = "Hello";
var s2 = s1.ToLower();

Console.WriteLine(s1);   // prints Hello
Console.WriteLine(s2);   // prints hello

This is called non-destructive mutation: The original string s1 still exists, it has not been destroyed. On the other hand, sb.Append("!") in the very first example was destructive: The version of sb containing Hello (without exclamation mark) is no longer accessible.

(Obviously, you can re-use the same variable name when lowercasing a string, e.g. s = s.ToLower(). But that does not change the fact that ToLower creates a new object rather than modifying the old one in-place. s = ... ensures that the variable s points to the new object afterwards.)


So, what does this have to do with anonymous types? Anonymous types in C# are immutable:

var myObject = new { A = 1, B = 2 };

myObject.B = 3;   // <- yields a compile-time error

C#9 introduced the with keyword, which allows you to create a new object which is an exact copy of the original object, except for the values you want to change:

var o1 = new { A = 1, B = 2 };
var o2 = o1 with { B = 3 };
    
// o1: A = 1, B = 2
// o2: A = 1, B = 3
Pantechnicon answered 22/8, 2022 at 12:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.