Readonly parameters with the in modifier

C# has a lesser used in parameter modifier which prevents parameter value modification

Home DailyDrop

Daily Knowledge Drop

The in parameter modifying keyword is used to cause a parameter be passed by reference, and ensure that cannot be modified in the method.

The in modifier's usage is similar to the ref and out keywords, except ref parameters can be modified and out parameters must be modified/set, while the in modifier effectively makes the parameter read-only.


Types

Simple value types

First lets have a look at how value types are handled in a few simple examples:

int originalValue = 1001;
InKeywordMethod(originalValue);

// parameter used in keyword
void InKeywordMethod(in int theValue)
{
    // this is not allowed and 
    // will not compile if uncommented
    // theValue = 999;
}

If uncommented, the application will not compile with the error:

Cannot assign to variable 'in int' because it is a readonly variable

As expected based on the introduction, with the use of the in keyword, the theValue variable is read-only inside the scope of the method, and cannot be modified.


Structure value types

The in keyword applied to a struct (a value type) parameter, yields in the same results as in the previous example with sample value types.

Consider the following struct:

public struct StructOptions
{
    public int IntValue { get; set; }
    public string StringValue { get; set; }
}

And it's usage:

var sOptions = new StructOptions
{
    IntValue = 759,
    StringValue = "StringValue"
};
InStructKeywordMethod(sOptions);

void InStructKeywordMethod(in StructOptions options)
{
    // this is not allowed and will not compile if uncommented
    // options.IntValue = 100;

    // this is also not allowed and will result in an error
    /*
    options = new StructOptions
    {
        IntValue = 123,
        StringValue = "NewStringValue!"
    }
    */
}

The properties of the struct as well as the struct itself are both read-only.


Reference types

Reference types however operate slightly differently when used with the in keyword.

We will use the same Options data structure as in the previous example, however this time define it as a class instead of a struct:

public class Options
{
    public int IntValue { get; set; }

    public string StringValue { get; set; }
}

And it's usage:

var options = new Options
{
    IntValue = 759,
    StringValue = "StringValue"
};

Console.WriteLine(options.IntValue);
InClassKeywordMethod(options);
Console.WriteLine(options.IntValue);

void InClassKeywordMethod(in Options options)
{
    // This is allowed!
    options.IntValue = 123;
}

With the reference type, modifications of its properties are allowed. Running the above code does not result in any compiler errors, with the output as follows:

759
123

However, modification of the class instance (not it's properties) is NOT allowed, and will result in a compiler error:

void InClassKeywordMethod(in Options options)
{
    // Cannot assign to variable 'in Options' because it is a readonly variable
    /*
    options = new Options
    {
        IntValue = 123,
        StringValue = "NewStringValue"
    };
    */
}

Notes

Not a modifier which will see everyday use, but interesting all the same. If using the in keyword, keep in mind that reference types properties can still be modified, and consider other options to make them readonly (removing the set accessor, for example)


References

in parameter modifier


Daily Drop 128: 01-08-2022

At the start of 2022 I set myself the goal of learning one new coding related piece of knowledge a day.
It could be anything - some.NET / C# functionality I wasn't aware of, a design practice, a cool new coding technique, or just something I find interesting. It could be something I knew at one point but had forgotten, or something completely new, which I may or may never actually use.

The Daily Drop is a record of these pieces of knowledge - writing about and summarizing them helps re-enforce the information for myself, as well as potentially helps others learn something new as well.
c# .net in parameter modifier