Search code examples
c#value-type

Passing immutable value types by reference by default


Usally I choose between struct and class not because of memory issues but because of semantics of the type. Some of my value types have quite large memory footprint, sometimes too large to copy this data all the time. So I wonder if it is a good idea to pass immutable value objects always by reference? Since the objects are immutable they cannot by modified by methods that accept them by reference. Are there other issues when passing by reference?


Solution

  • Some of my value types have quite large memory footprint

    That suggests they shouldn't be value types, from an implementation point of view. From "Design Guidelines for Developing Class Libraries", section "Choosing Between Classes And Structures":

    Do not define a structure unless the type has all of the following characteristics:

    • It logically represents a single value, similar to primitive types (integer, double, and so on).
    • It has an instance size smaller than 16 bytes.
    • It is immutable.
    • It will not have to be boxed frequently.

    It sounds like you should be creating immutable reference types instead. In many ways they end up "feeling" like value objects anyway (think strings) but you won't need to worry about the efficiency of passing them around.

    "Immutability" for value types is a slightly fluid concept - and it certainly doesn't mean that using ref is safe:

    // int is immutable, right?
    int x = 5;
    Foo(ref x);
    Console.WriteLine(x); // Eek, prints 6...
    ...
    void Foo(ref int y)
    {
        y = 6;
    }
    

    We're not changing one part of the value - we're replacing the whole of the value of x with an entirely different value.

    Immutability is somewhat easier to think about when it comes to reference types - although even then you can have an object which in itself won't change, but can refer to mutable objects...