Replies: 1 comment 4 replies
-
This is the intended and supported behavior of hte runtime as i understand it. DIM will call through a boxed (as the interface) copy of the struct. So when teh interface method runs it mutates that copy, and the original does not see it. An analyzer seems fine here. Requests for that would go to dotnet/roslyn-analyzers
First, it's more that there was no other way to implement it. In the interface 'this' isn't some value type that the runtime can then go mutate. It's not a constrained generic type parameter either. So there's no way for the original value to get mutated in the case of value types. Known limitation of hte runtime which the language has a correspondence with. Second, this is well outside the bounds of what DIM was intended for. Adding default behavior for mutable structs was definitely not something we felt was very important to make work. The primary use case was to be able to version interfaces in a compatible fashion without having an ABI break. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
I'm using default interface methods for the first time and just encountered some unexpected behaviour.
SharpLab
When passing the reference through the generic method, it seems that there's a value copy happening somewhere and eating the increment.
The boxed version works as expected.
SharpLab
I find it particularly strange that this behaves differently from calling a non DIM interface member.
SharpLab
I assume that this is intended behaviour, but it's not very intuitive and quite unhelpful. I had expected that the generics would allow me to call the interface method without boxing, but while it does get called, it's only on a copy.
Thinking through the consequences of this, I suppose that it means that any generic method that calls a DIM is required to put a
class
constraint on it in order to get the expected behaviour, right? Otherwise, it could be called with a value type and appear to be working but silently fail. The issue I see with that is that adding a DIM to an interface may require adding aclass
constraint to an existing API method, which would be a breaking change. One of the main goals of DIMs was to allow adding interface members without it being a breaking change.Is there a way to get the behaviour that I expected without boxing?
What's the design reason behind this behaviour? I tried to find documentation on DIMs that would clarify this but haven't been able to find anything substantial, and I couldn't see this question of value types addressed when I skimmed the various discussions on here. Is there an up to date language specification somewhere? The only thing that I can find is a C#6 Draft... which obviously doesn't address DIM behaviour at all.
Is there any point in proposing a change to this? I assume not because that would break backwards compatibility.
I think there should at least be an analyzer warning here somewhere!
Beta Was this translation helpful? Give feedback.
All reactions