In C# 7.2, are readonly structs always passed to functions as if the "in" parameter is present? If not, in what case would it be useful to copy the memory given that it's readonly?
I have a readonly struct:
public readonly struct Vec2
{
public readonly double X;
public readonly double Y;
}
So would there be a performance difference between these two methods when called billions of times:
public double Magnitude1(Vec2 v)
{
return Math.Sqrt(v.X*v.X + v.Y*v.Y);
}
public double Magnitude2(in Vec2 v)
{
return Math.Sqrt(v.X*v.X + v.Y*v.Y);
}
And if so, why doesn't the compiler recognize that Vec2 is a readonly struct and just pass it as if "in" were present? Is there an instance where you might want to pass a readonly struct without the "in" modifier?
The readonly keyword is a C# modifier used to limit access to all the data members of a struct. If the readonly modifier is used in the declaration of a struct, then: The members of the struct are read-only. None of the members can have setters. A parameterized constructor is used to initialize the data members.
Declaring in parameters in parameters are declared by using in keyword as a modifier in the parameter signature. For all purposes the in parameter is treated as a readonly variable. Most of the restrictions on the use of in parameters inside the method are the same as with readonly fields.
Yes they can. It depends. Many hold the stance that a struct should be immutable, and in this case, holding a reference to an object could mean it isn't. But it depends on the situation.
A structure type can't inherit from other class or structure type and it can't be the base of a class. However, a structure type can implement interfaces.
Are readonly structs always passed to functions as if the "in" parameter is present?
No. Without the in
modifier, readonly
structs are passed by value, not by reference.
If not, in what case would it be useful to copy the memory given that it's readonly?
It would be useful to copy the memory if you wanted to guarantee the memory didn't change. Keep in mind that a struct can be changed even if it's readonly
. For example:
readonly struct S
{
public readonly int I;
public S(int i) { this.I = i; }
}
class Program
{
static S s1 = new S(1);
static void Main()
{
A(s1);
}
static void A(in S s2)
{
Console.Write(s2.I);
s1 = new S(2); // This is legal even though S is readonly!
Console.Write(s2.I);
}
}
With the in
modifier on parameter s2
, the output is 12. Without the in
modifier, the output is 11.
This difference in behavior means the compiler cannot transparently add in
modifiers to readonly struct
parameters. (Even if method A
didn't modify s1
, another thread could.)
So would there be a performance difference between these two methods when called billions of times?
There might be; measure it and see. I'd expect that the larger the struct, the slower it would be to pass by value.
And if so, why doesn't the compiler recognize that Vec2 is a readonly struct and just pass it as if "in" were present? Is there an instance where you might want to pass a readonly struct without the "in" modifier?
Maybe if the struct
were very small (say, 8 bytes or less), passing by value (e.g., in a CPU register) could be cheaper than passing by reference (and then having to dereference the pointer).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With