C# 8.0 Interfaces are not really Interfaces anymore
C# 8.0 ships with the wonderfully horrible idea of interfaces with default impleme...
For further actions, you may consider blocking this person and/or reporting abuse
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.
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.
Why interface default implementations in C# are a great thing
Lolle2000la ・ Sep 5 ・ 5 min read
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.
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
orCanBounce
fall in the same category of trait classes.Hey, great article. I'll play with it as it look really fun
Also, shouldn't ShapeTraits methods be static?
yes! well spotted.
Porting code from Java just got a lot easier though, because of this.
Or one could simply use the good old decorator pattern.