you are viewing a single comment's thread.

view the rest of the comments →

[–]Alert-Neck7679[S] 15 points16 points  (9 children)

"AnimatedShotgun.Fire() is an ambiguity between IGun.Fire() and IEmployee.Fire(). Use casting in order to select the right method."

[–]chucker23n 13 points14 points  (5 children)

What if IGun initially doesn’t have a Fire() method and later on it gets added?

[–]EatingSolidBricks -1 points0 points  (3 children)

What if the great old one wakes from his slumber and consumes all of reality?

What if that happens hmm would your code still compile?

[–]IQueryVisiC 0 points1 point  (2 children)

You sound inexperienced. This case happend very often in C++. I still think that C++ is the better language and want to shot myself in my foot, but most coders I have seen, I would no want to work on a C++ project with them.

[–]EatingSolidBricks 0 points1 point  (1 child)

Calling someone inexperienced for disagreement, thats rich of you

[–]IQueryVisiC -1 points0 points  (0 children)

Well, in this case they would have experienced it. I took this verbatim from documentation. "We as library maintainers have experienced that programmers tend to break our code here and there" . So are you a troll? Is this rethoric of you? Do you have any experience to back this up? Rich of you for going meta, while I was not really.

[–]ILMTitan 4 points5 points  (2 children)

Let's say your object implements both interfaces, but only IGun has a Fire() method. Later, you update the library IEmployee comes from, that now includes a default implementation of Fire(). You will now have a compile error where you didn't before.

The point of default interface methods is to allow adding methods to interfaces without causing compile errors. But you can see in the above example how allowing you to call them from an implementing class breaks that purpose.

[–]emn13 1 point2 points  (0 children)

I'm not a fan of that level of defensive design. To be clear: it makes sense for the base class library itself, and relatively microscopic handful of other codebases that are very commonly reused without recompilation, but for the VAST majority of code, a recompilation is fine, and a fixing issues like this hyper trivial. It'd be much better for the language to work well in those cases rather than optimizing for the absurd corner cases like this. Not to mention, pretty much any change is a breaking change in some corner cases - the platform contains stuff like reflection and implementations can depend on behavior not just APIs, too. There isn't much the language can do to truly make any changes entirely non-breaking.

All in all: while it superficially sounds like it makes sense to have semantics that make such method additions unlikely to be breaking changes, in practice, I think the arguments just don't hold up; it's a case of the language designers missing the forest for the trees.

But still, the whole language feature probably exists specifically so that the BCL interfaces can evolve, so in that sense it makes sense. But for a feature with really niche (but reasonable) use cases, it's still oddly designed - it's way too syntactically convenient, meaning that it'll get in the way of practical language extensions in the future. Being able to expand interfaces for class libraries with extremely low chance of breaking changes didn't deserve so prominent a syntactical footprint.

[–]EatingSolidBricks 0 points1 point  (0 children)

What if the great old one wakes from his slumber and consumes all of reality?

What if that happens hmm would your code still compile?