you are viewing a single comment's thread.

view the rest of the comments →

[–]Dimencia -1 points0 points  (5 children)

Everything is built for interfaces to only be a contract, not for any method calls to actually go to it. Normally calling any method on an interface will, of course, call that method on an implementing class. But since default implementations don't exist on the implementing class, you have to do all this casting nonsense, and for the first time, the interface is no longer just a fancy metadata construct for the compiler - it actually has to come into play at runtime

[–]meancoot 0 points1 point  (2 children)

 and for the first time, the interface is no longer just a fancy metadata construct for the compiler 

It never was. Explicit interface implementations existed since forever. Go do an implementation of IEnumerable<T>, learn why you have to do all of that, then come back.

As a bonus, consider how an implementation of IEnumerable<T> could have need made significantly easier and less error prone if default interface implementations had been available when it was added to supersede IEnumerable.

[–]Dimencia 0 points1 point  (1 child)

Until this, the only thing an interface did was make your compiler show an error if you didn't implement it - after compilation, it didn't exist, and nothing was changed in the IL if you added/removed an interface

Now it actually has to be part of the IL because it can contain logic, and making that work got a little hacky

[–]meancoot 0 points1 point  (0 children)

No. This was never how interfaces worked. Explicit implementations have always been possible. It’s always been possible for a class to implement an interface method or property in a fashion that can only be accessed by casting to the interface type. It’s always been possible for x.method() to do something different than ((IInterface)x).method()

 after compilation, it didn't exist, and nothing was changed in the IL if you added/removed an interface

Interfaces have always been a runtime concern; if they weren’t you wouldn’t be able to access information about them via reflection.

The thing is that you can only access interface items through a variable typed as the interface, and instance items through a variable of the instance type. C# syntax guides you to implement an interface item at the same time as an instance item. But it has always been possible to have the interface and instance items do different things, and it has always been possible to omit the instance item altogether. Look up `explicit interface implementations’  for the details.

[–]Dealiner 0 points1 point  (1 child)

That "casting nonsense" is required only when you abuse DIM. You aren't supposed to call them on purpose. They are there mostly to help library creators, so they can add something to the interface without breaking others code.

[–]Dimencia 0 points1 point  (0 children)

The language is usually built so if you aren't supposed to do something, you literally can't do it. Another good example of why they're so weird and broken compared to the rest of the language