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
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.