'How do I make a struct immutable?

All over Stack Overflow and the internet I see that it is a good design principle to keep structs immutable. Unfortunately, I never see any implementation that actually causes these structs to be truly immutable.

Assuming that a struct does not have any reference types inside it, how do I actually make a struct immutable? That is, how do I prevent the mutation of any of its primitive field (perhaps by a compile-time/runtime exception)?

I wrote a simple test attempting make a struct immutable, but not even using the System.ComponentModel.ImmutableObjectAttribute worked:

class Program
{
    static void Main(string[] args)
    {
        ImmutableStruct immStruct1 = new ImmutableStruct();
        Console.WriteLine(immStruct1); //Before mutation.

        immStruct1.field1 = 1;
        immStruct1.field2 = "Hello";
        immStruct1.field3 = new object();
        Console.WriteLine(immStruct1); //After 1st mutation.

        immStruct1.field1 = 2;
        immStruct1.field2 = "World";
        immStruct1.field3 = new object();
        Console.WriteLine(immStruct1); //After 2nd mutation.

        Console.ReadKey();
    }
}

[ImmutableObject(true)]
struct ImmutableStruct
{
    public int field1;
    public string field2;
    public object field3;

    public override string ToString()
    {
        string field3String = "null";
        if (field3 != null)
        {
            field3String = field3.GetHashCode().ToString();
        }
        return String.Format("Field1: {0}, Field2: {1}, Field3: {2}", field1, field2, field3String);
    }
}


Solution 1:[1]

Keep your immutable data private:

struct ImmutableStruct
{
    private int field1;
    private string field2;
    private object field3;

    public ImmutableStruct(int f1, string f2, object f3)
    {
        field1 = f1;
        field2 = f2;
        field3 = f3;
    }

    public int Field1 => field1;
    public string Field2 => field2;
    public object Field3 => field3;
}

Or less cluttered:

struct ImmutableStruct
{
    public ImmutableStruct(int f1, string f2, object f3)
    {
        Field1 = f1;
        Field2 = f2;
        Field3 = f3;
    }

    public int Field1 { get; }
    public string Field2 { get; }
    public object Field3 { get; }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1