-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Don't use interfaces for sharing Tuple implementation methods #44684
Conversation
I couldn't figure out the best area label to add to this PR. If you have write-permissions please help me learn by adding exactly one area label. |
What does pull System.Tuple into the dependency closure in typical apps? I thought that they are really only used by F#. |
Tuples are still used even inside SPC. I looked at replacing them which would help too but there is no good replacement as they are used at places where valuetuples would have to go via object boxing/unboxing |
@dsyme Any concerns about this change from the F#? |
I would be nice to include some numbers for these type of changes in PR descriptions, e.g. how much smaller trimmed "Hello world" gets so we can collectively develop better understanding how much different patterns cost. |
I wonder if record is suitable here. |
I do not think records would be good alternative. Records come with a quite a bit of baggage, some of which would be impossible to trim. The C# auto-implements about 10 methods for record. It is about 10x more than what one needs to pass a tuple of values around. I think the light weight alternative for the current usage of Tuple in CoreLib would look like this:
And it would be used like this:
|
This case is a bit tricky to estimate. For hello-world it's about 3kb, for real app it can be probably 10kb or even more as it depends on how many types which implement such interfaces will exist (that includes other tuple types as well).
Yeah, I was wondering if introducing internal tuple like types for a few payloads we need them is better alternative (we did something similar in Mono). |
I looked it over and it seems semantics are precisely preserved, there is no actual semantic change here, and we're just avoiding an unnecessary dispatch via IStructuralEquatable, which can only be good from the F# perspective |
Tuples add a dependency on rarely used interfaces which block them from trimming everywhere. Instead of virtual call over interface share the implementation as a separate method. There is a corner case change in behaviour. As Tuple classes are not sealed, it was possible to override them with another custom IStructuralEquatable implementation. The object-based Equals implementation would end up calling custom explicit interface which I guess is unintended behaviour. The same would happen with IStructuralComparable.
Tuples add a dependency on rarely used interfaces which block them from
trimming everywhere. Instead of virtual call over interface share
the implementation as a separate method.
There is a corner case change in behaviour.
As Tuple classes are not sealed, it was possible to override them with
another custom IStructuralEquatable implementation. The object-based
Equals implementation would end up calling custom explicit interface
which I guess is unintended behaviour. The same would happen with
IStructuralComparable.
@stephentoub @jkotas (I'll fix the remaining Tuples if there are no objections)