For me the biggest benefit of default interface implementations is (binary) backwards compactability and interoperability with Java. And I think originally that was it's purpose.
When you use interfaces as contacts for extensions you would have to make a new interface to retain comparability with old implementers, and you cannot break all 2 week old extensions for some new features.
That's what I'm excited about.
I always thought as traits being a side-product. And as I read the discussions and the then-WIP spec of them it sounded like it being one
I have made an article myself in response to this article.
It outlines why I think that default interfaces are great. I actually agree about them not being useful as traits (because of confusion), but have a few other reasons that make me excited about them.
Great post Patrick, thanks for sharing! Been thinking about something like this for a while now, have you explored the ability to add traits at runtime ? That’s the nugget I haven’t able to crack (in a satisfactory manner).
Interesting suggestion - I'll take a crack at it :] that would make traits really powerful.
👏 let us know how you get on and if we can help, I’d be happy to.
Fun thought experiment, indeed. But has some limitations as well.
What if you need some data for your Traits? Where will the data be accessable? CanRoll could have properties, like Velocity or Acceleration. However, than the ITrait<T> interface is no marker interface anymore. To access this data you'll need a "T Value" property in ITrait. Hence, the traited class would need a Value-property per Trait.
The pseudo traits could have name collisions as well. What if you implement "public static void Roll(this ITrait<CanRickRoll> roller)" and assign ITrait<CanRickRoll> on Ball? What does "ball.Roll();" do?
Using this pseudo trait pattern would require to keep this limitations in mind. The default interface sure have their own set of limitations. But they become standard for all code bases of C#8.0 and above, so all developer can align themselves to this specific limitations and learn to deal with it. Integrating the pseudo trait pattern into a code base of C#8.0 and above would consequetly mean to potentially deal with limitations of default interfaces and the pseudo trait pattern.
EDIT: Manually escaped < and >
What is the point of having Trait class here instead of traits being just an empty interface? Just to know it is a "pseudo trait"?
It's a filter/grouping, so you know that what you're extending is definitely a (pseudo) trait. You can do without it - it's definitely a stylistic choice. But I like the safety of it. Your CanRoll or CanBounce fall in the same category of trait classes.
Porting code from Java just got a lot easier though, because of this.
Or one could simply use the good old decorator pattern.
Hey, great article. I'll play with it as it look really fun
Also, shouldn't ShapeTraits methods be static?
yes! well spotted.
We're a place where coders share, stay up-to-date and grow their careers.
We strive for transparency and don't collect excess data.