DEV Community

Cover image for Pseudo Traits in C#

Pseudo Traits in C#

Henrick Tissink on September 04, 2019

C# 8.0 Interfaces are not really Interfaces anymore C# 8.0 ships with the wonderfully horrible idea of interfaces with default impleme...
Collapse
 
radumg profile image
Radu Gidei

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).

Collapse
 
htissink profile image
Henrick Tissink

Interesting suggestion - I'll take a crack at it :] that would make traits really powerful.

Collapse
 
radumg profile image
Radu Gidei

👏 let us know how you get on and if we can help, I’d be happy to.

Collapse
 
lolle2000la profile image
Lolle2000la

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

Collapse
 
lolle2000la profile image
Lolle2000la • Edited

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.

Collapse
 
yeah69 profile image
Dima • Edited

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 >

Collapse
 
bandysc profile image
Bartosz Korczyński

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"?

Collapse
 
htissink profile image
Henrick Tissink

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.

Collapse
 
dbarwikowski profile image
Daniel Barwikowski

Hey, great article. I'll play with it as it look really fun

Also, shouldn't ShapeTraits methods be static?

Collapse
 
htissink profile image
Henrick Tissink

yes! well spotted.

Collapse
 
agrothe profile image
Andrew Grothe

Porting code from Java just got a lot easier though, because of this.

Collapse
 
webbes profile image
webbes

Or one could simply use the good old decorator pattern.