Replies: 11 comments
-
Why not make Vector3 a readonly struct itself?
That would break cases where getters do mutate, thus violating the contract of "readonly ref". It's not really readonly if the thing you call can go and mutate it :) |
Beta Was this translation helpful? Give feedback.
-
Presumably the Vector3 you are talking about is not |
Beta Was this translation helpful? Give feedback.
-
@CyrusNajmabadi unless for auto properties. |
Beta Was this translation helpful? Give feedback.
-
Property getters produce copies of the values they return, not on the value they're called on. Or am I missing something? |
Beta Was this translation helpful? Give feedback.
-
@GeirGrusom when struct is readonly calling any method on it will result in copy of struct it self and method is called on copied instance instead so that changes made to copy does not affect original value. this way readonly struct remains truly immutable. (this is not true for readonly classes) getter is just a method so that also causes copy. |
Beta Was this translation helpful? Give feedback.
-
Oh I was unaware. Thanks, @MkazemAkhgary. |
Beta Was this translation helpful? Give feedback.
-
What auto properties have to do with this? They're just syntax sugar. |
Beta Was this translation helpful? Give feedback.
-
@mikedn all this proposal is about to make optimization on pure methods like getter (and prevent unnecessary copy) . but it is possible for normal getter to mutate struct value, thus its not safe to make that optimization on all getters. how ever it is possible to safely pass reference of value directly to auto getter because its known to be pure method. this will be optimization by compiler. or maybe CLR. I don't know. |
Beta Was this translation helpful? Give feedback.
-
At the level where this matters there's no such thing as an auto getter. Again, auto properties are just syntactic sugar. The proper solution would probably be to be able to mark methods as Another solution would be for the JIT compiler to eliminate the copy since such trivial getters are inlined and thus it is obvious to the JIT that they do not mutate the value. Currently the JIT doesn't do that and I'm not sure if it's possible to add this optimization to it. It may turn out that the use of |
Beta Was this translation helpful? Give feedback.
-
"const functions" is just a more more specific feature than "readonly struct" right? Either way you have to annotate your types, it won't get magically light up for any assembly. Furthermore, there is an argument (not mine) that it is not eventually practical because immutable types need different requirements so we need separate types to represent immutable/non-immutable types.. See #421. I suspect that's why the team continue to invest on type-level modifiers like "readonly struct" or "immutable types" (https://github.com/dotnet/roslyn/issues/159) rather than handling this on function and object level.
I partially agree with the last part but it seems like features are not prioritized just based on what makes more sense for the features themselves. One example is I imagine a couple of reasons for this: (1) readonly locals are hard to adopt because C# have been a mutable-by-default language for a long time now (2) readonly structs are a way of optimizing ref locals and may have a greater value if we have them alongside These kinds of reasons probably apply to "const functions" as well in a way or another. |
Beta Was this translation helpful? Give feedback.
-
Yes, methods would need to be annotated. You can't expect the compiler to figure out that a method doesn't change the value. The method may be in another assembly and the compiler won't be able to see its implementation.
Immutable types are a very different beast.
To me it looks like they prioritize based on what can be easily implemented. That works in some cases but it's dangerous in language design, it can introduce unintuitive behavior that's difficult or impossible to fix later. Maybe this no longer matters at this point, the language already features unintuitive behavior in connection to value types. Ever tried to call a mutating method on a value stored in a list (e.g.
Do you mean readonly methods? If that's the case then yes, they're difficult to add to the language after the fact. To be clear, I'm not advocating for readonly methods to be added exactly because of this. But it should be clear to everyone that having |
Beta Was this translation helpful? Give feedback.
-
This example is copied from an issue dealing with ref readonly parameters.
static void Add (in Vector3 v1, in Vector3 v2, out var result)
{
// OK
result = new Vector3(v1.X +v2.X, v1.Y + v2.Y, v1.Z + v2.Z);
}
The in keyword in this example is pointless, because implicit copies would be made to access property getters of X and Y unless Vector3 is declared a ref readonly struct. Since property getters are almost always free of observable side-effects, it might make sense to special case access to getters and avoid creating implicit copies when using them.
Beta Was this translation helpful? Give feedback.
All reactions