Uh oh!
There was an error while loading. Please reload this page.
Make ValueTuple members that can be made readonly readonly - #90773
Make ValueTuple members that can be made readonly readonly#90773Neme12 wants to merge 3 commits into
Conversation
You also have to update the reference assembly in https://github.com/dotnet/runtime/blob/64243bbf5e9ee53c0c4c5678f2cd8c7f1c9b4f6f/src/libraries/System.Runtime/ref/System.Runtime.cs#L7116-L7294. |
Neme12
commented
Aug 17, 2023
Thanks. |
Doesn't this break C# tuple contract? For example // Valid codevartuple=(1,2);tuple.Item2=3; |
huoyaoyuan
commented
Aug 18, 2023
Only the 0-ary ValueTuple is marked as readonly as a whole type. The members of others are still writable. |
ghost
commented
Aug 18, 2023
Tagging subscribers to this area: @dotnet/area-system-runtime Issue DetailsI applied readonly to all methods except for GetHashCode and ToString, which can't be made readonly (or can be, but it would make copies of the items) because they forward to methods on the individual items that could potentially modify them.
|
jozkee
left a comment
There was a problem hiding this comment.
Thanks for working on this.
How does GetHashCode() and ToString() create a defensive copy? sharplab.io shows identical asm.
Also, there have been other issues filed where this is being discussed. Just referencing them here.
- #29403 (specific to ValueTuple)
- #1718 (more general approach)
- #46675 (comment)
adamsitnik
commented
Nov 2, 2023
@dotnet/fxdc does applying @stephentoub@jkotas what is our current strategy for similar changes? I saw #46675 (comment)
And I believe that most of the methods marked as readonly in this PR (Equals, indexer, GetHashCode) will never mutate. But it's not very clear to me what we would gain from it. |
stephentoub
commented
Nov 2, 2023
We've generally preferred to do so, yes, ideally in bulk.
The main consumer gain for us marking something Let's say you have: (long,long,long,long)value= ...;Foo(refvalue);
...void Foo(ref(long,long,long,long)data){data.GetHashCode();}The compiler doesn't need to do anything special here around preventing mutation. But if instead the code was: (long,long,long,long)value= ...;Foo(invalue);
...void Foo(in(long,long,long,long)data){data.GetHashCode();}The voidFoo(ref(long,long,long,long)data){(long,long,long,long)copy=data;copy.GetHashCode();}Whether that has any actual performance impact depends on a variety of factors, e.g. if the method being called is inlined, there's a good chance the JIT will eliminate the copy. |
| } | ||
| int IStructuralComparable.CompareTo(object? other, IComparer comparer) | ||
| readonly int IStructuralComparable.CompareTo(object? other, IComparer comparer) |
There was a problem hiding this comment.
Putting readonly on explicit interface implementations isn't going to buy you anything. These can only be accessed via interface references and those don't have defensive copy semantics.
I'm actually a bit surprised we allow this syntax.
tannergooding
commented
Nov 2, 2023
The other notable case is That being said, this is all generic code and we're just trading one copy for another copy here. That is, today, if you have If you instead mark In the case where all types are |
tannergooding
commented
Nov 2, 2023
The below sharplab link gives a simplistic example of a struct where |
adamsitnik
left a comment
There was a problem hiding this comment.
does applying readonly to a type and/or method requires going through API review (removing it would cause a breaking change)?
We've generally preferred to do so, yes, ideally in bulk.
In such a case I am going to convert this PR to a draft and create a new API proposal based on the ref file changes.
huoyaoyuan
commented
Nov 7, 2023
ghost
commented
Dec 7, 2023
Draft Pull Request was automatically closed for 30 days of inactivity. Please let us know if you'd like to reopen it. |
terrajobst
commented
Dec 7, 2023
Before we close this, is this intended to still be one? From an API review standpoint, this affects public surface area and should normally go through API review but my care level is relatively low. Unless anyone on @dotnet/fxdc objects, I'm OK with letting these kind of changes be handled by PR review alone. |
ghost
commented
Jan 6, 2024
Draft Pull Request was automatically closed for 30 days of inactivity. Please let us know if you'd like to reopen it. |
I applied readonly to all methods except for GetHashCode and ToString, which can't be made readonly (or can be, but it would make copies of the items) because they forward to methods on the individual items that could potentially modify them.