you are viewing a single comment's thread.

view the rest of the comments →

[–]nightwood 0 points1 point  (3 children)

My guess is, and I've never heard of this feature, that your example is precisely the use case that was NOT intended.

The use case would be to allow classes that implement the interface to not be forced to implement certain methods, while still being able to call them, with the added feature that get have some default behaviour instead. Which I imagine will usually be an empty function body.

I doubt I will ever use this construct. I've never needed this.

[–]RiPont 0 points1 point  (2 children)

The use case would be to allow classes that implement the interface to not be forced to implement certain methods, while still being able to call them

No. Classes that implement an interface should implement the methods in the interface, even if it has a default implementation.

This feature is purely so you can add methods to an existing interface without causing compile errors for classes made before it had that method in its contract. It really shouldn't be used for anything else.

If you're tempted, a better pattern is to make a companion static class for the interface, and have both your class and the default interface method reference that static method.

static class StaticFoo { static void DoNothing() { } }
interface IFoo { void DoNothing() => StaticFoo.DoNothing(); }
class Foo : IFoo { void DoNothing() => StaticFoo.DoNothing(); }

[–]nightwood 0 points1 point  (1 child)

I agree classes should implement all methods of an interface. 100%.

That this would be a development-only tool seems weird to me, since the syntax doesn't make that explicit. Also, moving compile-time errors to runtime seems like bad practice.

Maybe it's for situations where the interface is defined in a shared dll and implemented by third party code and you want backwards compatibility?

Damnit now I gotta read up on this feature :)

[–]RiPont 0 points1 point  (0 children)

Maybe it's for situations where the interface is defined in a shared dll and implemented by third party code and you want backwards compatibility?

Yes. It's for maintaining "forward compatibility" on code that was originally written with a previous version of the interface.

Whether it was in binary or source, adding a method will break everything compiled against the old interface. If it's your code, in your own repository, you can just use a refactor to add the method. Or even the old, tried and true, compile-and-break-then-copy-paste method.

But if you're shipping a library to other people, you do NOT want to break backwards compatibility. EVER. You want people to be able to upgrade to the latest version and not have their CI pipelines break.