How would you implement a “trait” design-pattern in C#?












43















I know the feature doesn't exist in C#, but PHP recently added a feature called Traits which I thought was a bit silly at first until I started thinking about it.



Say I have a base class called Client. Client has a single property called Name.



Now I'm developing a re-usable application that will be used by many different customers. All customers agree that a client should have a name, hence it being in the base-class.



Now Customer A comes along and says he also need to track the client's Weight. Customer B doesn't need the Weight, but he wants to track Height. Customer C wants to track both Weight and Height.



With traits, we could make the both the Weight and the Height features traits:



class ClientA extends Client use TClientWeight
class ClientB extends Client use TClientHeight
class ClientC extends Client use TClientWeight, TClientHeight


Now I can meet all my customers' needs without adding any extra fluff to the class. If my customer comes back later and says "Oh, I really like that feature, can I have it too?", I just update the class definition to include the extra trait.



How would you accomplish this in C#?



Interfaces don't work here because I want concrete definitions for the properties and any associated methods, and I don't want to re-implement them for each version of the class.



(By "customer", I mean a literal person who has employed me as a developer, whereas by "client" I'm referring a programming class; each of my customers has clients that they want to record information about)










share|improve this question




















  • 2





    Well, you can quite perfectly simulate traits in C# by using marker interfaces and extension methods.

    – Lucero
    May 23 '12 at 23:27






  • 1





    @Lucero Those are not traits and lack the ability to add new members (among other things). Nevertheless, extension methods are nifty.

    – user166390
    May 23 '12 at 23:29








  • 2





    @Lucero: That would work for adding extra methods, but what if I want to store additional data on the client object as well?

    – mpen
    May 23 '12 at 23:29






  • 1





    @Mark, then you need to have some ability to dynamically store data on arbitrary objects, which is not a feature of the runtime. I'll add some info on my answer on that regard.

    – Lucero
    May 23 '12 at 23:45






  • 2





    Traits are coming to C# in the form of default interface methods. See this proposal and the corresponding issue. (I'd post an answer but I don't know enough about it yet to post anything meaningful.)

    – Stijn
    Aug 25 '17 at 13:44
















43















I know the feature doesn't exist in C#, but PHP recently added a feature called Traits which I thought was a bit silly at first until I started thinking about it.



Say I have a base class called Client. Client has a single property called Name.



Now I'm developing a re-usable application that will be used by many different customers. All customers agree that a client should have a name, hence it being in the base-class.



Now Customer A comes along and says he also need to track the client's Weight. Customer B doesn't need the Weight, but he wants to track Height. Customer C wants to track both Weight and Height.



With traits, we could make the both the Weight and the Height features traits:



class ClientA extends Client use TClientWeight
class ClientB extends Client use TClientHeight
class ClientC extends Client use TClientWeight, TClientHeight


Now I can meet all my customers' needs without adding any extra fluff to the class. If my customer comes back later and says "Oh, I really like that feature, can I have it too?", I just update the class definition to include the extra trait.



How would you accomplish this in C#?



Interfaces don't work here because I want concrete definitions for the properties and any associated methods, and I don't want to re-implement them for each version of the class.



(By "customer", I mean a literal person who has employed me as a developer, whereas by "client" I'm referring a programming class; each of my customers has clients that they want to record information about)










share|improve this question




















  • 2





    Well, you can quite perfectly simulate traits in C# by using marker interfaces and extension methods.

    – Lucero
    May 23 '12 at 23:27






  • 1





    @Lucero Those are not traits and lack the ability to add new members (among other things). Nevertheless, extension methods are nifty.

    – user166390
    May 23 '12 at 23:29








  • 2





    @Lucero: That would work for adding extra methods, but what if I want to store additional data on the client object as well?

    – mpen
    May 23 '12 at 23:29






  • 1





    @Mark, then you need to have some ability to dynamically store data on arbitrary objects, which is not a feature of the runtime. I'll add some info on my answer on that regard.

    – Lucero
    May 23 '12 at 23:45






  • 2





    Traits are coming to C# in the form of default interface methods. See this proposal and the corresponding issue. (I'd post an answer but I don't know enough about it yet to post anything meaningful.)

    – Stijn
    Aug 25 '17 at 13:44














43












43








43


12






I know the feature doesn't exist in C#, but PHP recently added a feature called Traits which I thought was a bit silly at first until I started thinking about it.



Say I have a base class called Client. Client has a single property called Name.



Now I'm developing a re-usable application that will be used by many different customers. All customers agree that a client should have a name, hence it being in the base-class.



Now Customer A comes along and says he also need to track the client's Weight. Customer B doesn't need the Weight, but he wants to track Height. Customer C wants to track both Weight and Height.



With traits, we could make the both the Weight and the Height features traits:



class ClientA extends Client use TClientWeight
class ClientB extends Client use TClientHeight
class ClientC extends Client use TClientWeight, TClientHeight


Now I can meet all my customers' needs without adding any extra fluff to the class. If my customer comes back later and says "Oh, I really like that feature, can I have it too?", I just update the class definition to include the extra trait.



How would you accomplish this in C#?



Interfaces don't work here because I want concrete definitions for the properties and any associated methods, and I don't want to re-implement them for each version of the class.



(By "customer", I mean a literal person who has employed me as a developer, whereas by "client" I'm referring a programming class; each of my customers has clients that they want to record information about)










share|improve this question
















I know the feature doesn't exist in C#, but PHP recently added a feature called Traits which I thought was a bit silly at first until I started thinking about it.



Say I have a base class called Client. Client has a single property called Name.



Now I'm developing a re-usable application that will be used by many different customers. All customers agree that a client should have a name, hence it being in the base-class.



Now Customer A comes along and says he also need to track the client's Weight. Customer B doesn't need the Weight, but he wants to track Height. Customer C wants to track both Weight and Height.



With traits, we could make the both the Weight and the Height features traits:



class ClientA extends Client use TClientWeight
class ClientB extends Client use TClientHeight
class ClientC extends Client use TClientWeight, TClientHeight


Now I can meet all my customers' needs without adding any extra fluff to the class. If my customer comes back later and says "Oh, I really like that feature, can I have it too?", I just update the class definition to include the extra trait.



How would you accomplish this in C#?



Interfaces don't work here because I want concrete definitions for the properties and any associated methods, and I don't want to re-implement them for each version of the class.



(By "customer", I mean a literal person who has employed me as a developer, whereas by "client" I'm referring a programming class; each of my customers has clients that they want to record information about)







c# design-patterns traits code-reuse c#-8.0






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 23 '18 at 17:14









Panagiotis Kanavos

55.3k483110




55.3k483110










asked May 23 '12 at 23:22









mpenmpen

124k172648950




124k172648950








  • 2





    Well, you can quite perfectly simulate traits in C# by using marker interfaces and extension methods.

    – Lucero
    May 23 '12 at 23:27






  • 1





    @Lucero Those are not traits and lack the ability to add new members (among other things). Nevertheless, extension methods are nifty.

    – user166390
    May 23 '12 at 23:29








  • 2





    @Lucero: That would work for adding extra methods, but what if I want to store additional data on the client object as well?

    – mpen
    May 23 '12 at 23:29






  • 1





    @Mark, then you need to have some ability to dynamically store data on arbitrary objects, which is not a feature of the runtime. I'll add some info on my answer on that regard.

    – Lucero
    May 23 '12 at 23:45






  • 2





    Traits are coming to C# in the form of default interface methods. See this proposal and the corresponding issue. (I'd post an answer but I don't know enough about it yet to post anything meaningful.)

    – Stijn
    Aug 25 '17 at 13:44














  • 2





    Well, you can quite perfectly simulate traits in C# by using marker interfaces and extension methods.

    – Lucero
    May 23 '12 at 23:27






  • 1





    @Lucero Those are not traits and lack the ability to add new members (among other things). Nevertheless, extension methods are nifty.

    – user166390
    May 23 '12 at 23:29








  • 2





    @Lucero: That would work for adding extra methods, but what if I want to store additional data on the client object as well?

    – mpen
    May 23 '12 at 23:29






  • 1





    @Mark, then you need to have some ability to dynamically store data on arbitrary objects, which is not a feature of the runtime. I'll add some info on my answer on that regard.

    – Lucero
    May 23 '12 at 23:45






  • 2





    Traits are coming to C# in the form of default interface methods. See this proposal and the corresponding issue. (I'd post an answer but I don't know enough about it yet to post anything meaningful.)

    – Stijn
    Aug 25 '17 at 13:44








2




2





Well, you can quite perfectly simulate traits in C# by using marker interfaces and extension methods.

– Lucero
May 23 '12 at 23:27





Well, you can quite perfectly simulate traits in C# by using marker interfaces and extension methods.

– Lucero
May 23 '12 at 23:27




1




1





@Lucero Those are not traits and lack the ability to add new members (among other things). Nevertheless, extension methods are nifty.

– user166390
May 23 '12 at 23:29







@Lucero Those are not traits and lack the ability to add new members (among other things). Nevertheless, extension methods are nifty.

– user166390
May 23 '12 at 23:29






2




2





@Lucero: That would work for adding extra methods, but what if I want to store additional data on the client object as well?

– mpen
May 23 '12 at 23:29





@Lucero: That would work for adding extra methods, but what if I want to store additional data on the client object as well?

– mpen
May 23 '12 at 23:29




1




1





@Mark, then you need to have some ability to dynamically store data on arbitrary objects, which is not a feature of the runtime. I'll add some info on my answer on that regard.

– Lucero
May 23 '12 at 23:45





@Mark, then you need to have some ability to dynamically store data on arbitrary objects, which is not a feature of the runtime. I'll add some info on my answer on that regard.

– Lucero
May 23 '12 at 23:45




2




2





Traits are coming to C# in the form of default interface methods. See this proposal and the corresponding issue. (I'd post an answer but I don't know enough about it yet to post anything meaningful.)

– Stijn
Aug 25 '17 at 13:44





Traits are coming to C# in the form of default interface methods. See this proposal and the corresponding issue. (I'd post an answer but I don't know enough about it yet to post anything meaningful.)

– Stijn
Aug 25 '17 at 13:44












8 Answers
8






active

oldest

votes


















45














You can get the syntax by using marker interfaces and extension methods.



Prerequisite: the interfaces need to define the contract which is later used by the extension method. Basically the interface defines the contract for being able to "implement" a trait; ideally the class where you add the interface should already have all members of the interface present so that no additional implementation is required.



public class Client {
public double Weight { get; }

public double Height { get; }
}

public interface TClientWeight {
double Weight { get; }
}

public interface TClientHeight {
double Height { get; }
}

public class ClientA: Client, TClientWeight { }

public class ClientB: Client, TClientHeight { }

public class ClientC: Client, TClientWeight, TClientHeight { }

public static class TClientWeightMethods {
public static bool IsHeavierThan(this TClientWeight client, double weight) {
return client.Weight > weight;
}
// add more methods as you see fit
}

public static class TClientHeightMethods {
public static bool IsTallerThan(this TClientHeight client, double height) {
return client.Height > height;
}
// add more methods as you see fit
}


Use like this:



var ca = new ClientA();
ca.IsHeavierThan(10); // OK
ca.IsTallerThan(10); // compiler error


Edit: The question was raised how additional data could be stored. This can also be addressed by doing some extra coding:



public interface IDynamicObject {
bool TryGetAttribute(string key, out object value);
void SetAttribute(string key, object value);
// void RemoveAttribute(string key)
}

public class DynamicObject: IDynamicObject {
private readonly Dictionary<string, object> data = new Dictionary<string, object>(StringComparer.Ordinal);

bool IDynamicObject.TryGetAttribute(string key, out object value) {
return data.TryGet(key, out value);
}

void IDynamicObject.SetAttribute(string key, object value) {
data[key] = value;
}
}


And then, the trait methods can add and retrieve data if the "trait interface" inherits from IDynamicObject:



public class Client: DynamicObject { /* implementation see above */ }

public interface TClientWeight, IDynamicObject {
double Weight { get; }
}

public class ClientA: Client, TClientWeight { }

public static class TClientWeightMethods {
public static bool HasWeightChanged(this TClientWeight client) {
object oldWeight;
bool result = client.TryGetAttribute("oldWeight", out oldWeight) && client.Weight.Equals(oldWeight);
client.SetAttribute("oldWeight", client.Weight);
return result;
}
// add more methods as you see fit
}


Note: by implementing IDynamicMetaObjectProvider as well the object would even allow to expose the dynamic data through the DLR, making the access to the additional properties transparent when used with the dynamic keyword.






share|improve this answer





















  • 5





    So you're saying put all the data in the base class, and all the method implementations in extension methods that have hooks on the interfaces? It's curious solution, but perhaps workable. My only beef is that you're making the client classes carry a lot of "dead weight" (unused members). With some fancy serialization it won't need to be saved to disk, but it's still consuming memory.

    – mpen
    May 23 '12 at 23:46











  • "Sort of". I sure can't think of anything better within the C# language, so +1. I do not give this the same footing as a Trait, however. (A sever limitation is outlined by Mark.)

    – user166390
    May 23 '12 at 23:46













  • Err.. I guess with C# properties I only have to implement the property for each derived class and I can store the data there. It's a little bit redundant, but I guess it's better than re-implementing all the methods too.

    – mpen
    May 23 '12 at 23:48











  • To complete this answer, I'd still like to see you define a concrete member variable (all I see is properties). I'm not sure if you intend for me to define them in Client, or redefine them multiple times in ClientB and ClientC as needed.

    – mpen
    May 23 '12 at 23:58






  • 1





    @Mark, see my updates for dynamic data storage (implementing the serialization is left as an excercise to the reader ;) ). Since interfaces cannot define contracts for fields you cannot use fields as part of the "trait", but of course the properties can be read-write! I'm not saying that C# has traits, but rather that the extension methods can serve as reusable code blocks for interfaces, so that re-implementation of the methods is not required; of course the code has to have all needed members readily available on the interface.

    – Lucero
    May 24 '12 at 0:07





















8














C# language (at least to version 5) does not have support for Traits.



However, Scala has Traits and Scala runs on the JVM (and CLR). Therefore, it's not a matter of run-time, but simply that of the language.



Consider that Traits, at least at the Scala sense, can be thought of as "pretty magic to compile in proxy methods" (they do not affect the MRO, which is different from Mixins in Ruby). In C# the way to get this behavior would be to use interfaces and "lots of manual proxy methods" (e.g. composition).



This tedious process could be done with a hypothetical processor (perhaps automatic code generation for a partial class via templates?), but that's not C#.



Happy coding.






share|improve this answer


























  • I'm not exactly sure what this answers. Are you suggesting that I should hack together something to pre-process my C# code?

    – mpen
    May 23 '12 at 23:32











  • @Mark No. I was 1) Suggesting C#, the language, cannot support it (although perhaps with dynamic proxies? This level of magic is beyond me.) 2) That Traits do not affect the MRO and can be "simulated by hand"; that is, a Trait can be flattened into every Class it is mixed into, as with Composition.

    – user166390
    May 23 '12 at 23:33








  • 1





    @Mark Ahh, Method Resolution Order. That is, Traits (again, in the Scala sense which are still based on Single Inheritance run-time) do not actually affect the class hierarchy. There is no "trait class" added to the [virtual] dispatch tables. The methods/properties in the Traits are copied (during completing) into the respective classes. Here is are some papers about traits as used in Scala. Ordersky presents that Traits can be used in a SI runtime, which is why they are "baked in" at compilation.

    – user166390
    May 23 '12 at 23:38








  • 1





    @Mark This differs from a language like Ruby which will inject the "mixin" type (a form of traits) into the MRO (which is a form of alternating the class hierarchy, but with control and restrictions).

    – user166390
    May 23 '12 at 23:43








  • 2





    I'm hesitant to upvote you because you haven't provided me with anything concrete yet, just a lot of talk about other languages. I'm trying to figure out how I can borrow some of these ideas from Scala....but that's all built-in to the language. How's it transferable?

    – mpen
    May 23 '12 at 23:50



















5














I'd like to point to NRoles, an experiment with roles in C#, where roles are similar to traits.



NRoles uses a post-compiler to rewrite the IL and inject the methods into a class. This allows you to write code like that:



public class RSwitchable : Role
{
private bool on = false;
public void TurnOn() { on = true; }
public void TurnOff() { on = false; }
public bool IsOn { get { return on; } }
public bool IsOff { get { return !on; } }
}

public class RTunable : Role
{
public int Channel { get; private set; }
public void Seek(int step) { Channel += step; }
}

public class Radio : Does<RSwitchable>, Does<RTunable> { }


where class Radio implements RSwitchable and RTunable. Behind the scenes, Does<R> is an interface with no members, so basically Radio compiles to an empty class. The post-compilation IL rewriting injects the methods of RSwitchable and RTunable into Radio, which can then be used as if it really derived from the two roles (from another assembly):



var radio = new Radio();
radio.TurnOn();
radio.Seek(42);


To use radio directly before rewriting happened (that is, in the same assembly as where the Radio type is declared), you have to resort to extensions methods As<R>():



radio.As<RSwitchable>().TurnOn();
radio.As<RTunable>().Seek(42);


since the compiler would not allow to call TurnOn or Seek directly on the Radio class.






share|improve this answer































    5














    There is an academic project, developed by Stefan Reichart from the Software Composition Group at the University of Bern (Switzerland), which provides a true implementation of traits to the C# language.



    Have a look at the paper (PDF) on CSharpT for the full description of what he has done, based on the mono compiler.



    Here is a sample of what can be written:



    trait TCircle
    {
    public int Radius { get; set; }
    public int Surface { get { ... } }
    }

    trait TColor { ... }

    class MyCircle
    {
    uses { TCircle; TColor }
    }





    share|improve this answer































      3














      This is really an suggested extension to Lucero's answer where all the storage was in the base class.



      How about using dependency properties for this?



      This would have the effect of making the client classes light weight at run time when you have many properties that are not always set by every descendant. This is because the values are stored in a static member.



      using System.Windows;

      public class Client : DependencyObject
      {
      public string Name { get; set; }

      public Client(string name)
      {
      Name = name;
      }

      //add to descendant to use
      //public double Weight
      //{
      // get { return (double)GetValue(WeightProperty); }
      // set { SetValue(WeightProperty, value); }
      //}

      public static readonly DependencyProperty WeightProperty =
      DependencyProperty.Register("Weight", typeof(double), typeof(Client), new PropertyMetadata());


      //add to descendant to use
      //public double Height
      //{
      // get { return (double)GetValue(HeightProperty); }
      // set { SetValue(HeightProperty, value); }
      //}

      public static readonly DependencyProperty HeightProperty =
      DependencyProperty.Register("Height", typeof(double), typeof(Client), new PropertyMetadata());
      }

      public interface IWeight
      {
      double Weight { get; set; }
      }

      public interface IHeight
      {
      double Height { get; set; }
      }

      public class ClientA : Client, IWeight
      {
      public double Weight
      {
      get { return (double)GetValue(WeightProperty); }
      set { SetValue(WeightProperty, value); }
      }

      public ClientA(string name, double weight)
      : base(name)
      {
      Weight = weight;
      }
      }

      public class ClientB : Client, IHeight
      {
      public double Height
      {
      get { return (double)GetValue(HeightProperty); }
      set { SetValue(HeightProperty, value); }
      }

      public ClientB(string name, double height)
      : base(name)
      {
      Height = height;
      }
      }

      public class ClientC : Client, IHeight, IWeight
      {
      public double Height
      {
      get { return (double)GetValue(HeightProperty); }
      set { SetValue(HeightProperty, value); }
      }

      public double Weight
      {
      get { return (double)GetValue(WeightProperty); }
      set { SetValue(WeightProperty, value); }
      }

      public ClientC(string name, double weight, double height)
      : base(name)
      {
      Weight = weight;
      Height = height;
      }

      }

      public static class ClientExt
      {
      public static double HeightInches(this IHeight client)
      {
      return client.Height * 39.3700787;
      }

      public static double WeightPounds(this IWeight client)
      {
      return client.Weight * 2.20462262;
      }
      }





      share|improve this answer
























      • Why should we possibly use WPF classes here?

        – Javid
        Dec 15 '17 at 7:07



















      2














      Building on what Lucero suggested, I came up with this:



      internal class Program
      {
      private static void Main(string args)
      {
      var a = new ClientA("Adam", 68);
      var b = new ClientB("Bob", 1.75);
      var c = new ClientC("Cheryl", 54.4, 1.65);

      Console.WriteLine("{0} is {1:0.0} lbs.", a.Name, a.WeightPounds());
      Console.WriteLine("{0} is {1:0.0} inches tall.", b.Name, b.HeightInches());
      Console.WriteLine("{0} is {1:0.0} lbs and {2:0.0} inches.", c.Name, c.WeightPounds(), c.HeightInches());
      Console.ReadLine();
      }
      }

      public class Client
      {
      public string Name { get; set; }

      public Client(string name)
      {
      Name = name;
      }
      }

      public interface IWeight
      {
      double Weight { get; set; }
      }

      public interface IHeight
      {
      double Height { get; set; }
      }

      public class ClientA : Client, IWeight
      {
      public double Weight { get; set; }
      public ClientA(string name, double weight) : base(name)
      {
      Weight = weight;
      }
      }

      public class ClientB : Client, IHeight
      {
      public double Height { get; set; }
      public ClientB(string name, double height) : base(name)
      {
      Height = height;
      }
      }

      public class ClientC : Client, IWeight, IHeight
      {
      public double Weight { get; set; }
      public double Height { get; set; }
      public ClientC(string name, double weight, double height) : base(name)
      {
      Weight = weight;
      Height = height;
      }
      }

      public static class ClientExt
      {
      public static double HeightInches(this IHeight client)
      {
      return client.Height * 39.3700787;
      }

      public static double WeightPounds(this IWeight client)
      {
      return client.Weight * 2.20462262;
      }
      }


      Output:



      Adam is 149.9 lbs.
      Bob is 68.9 inches tall.
      Cheryl is 119.9 lbs and 65.0 inches.


      It isn't quite as nice as I'd like, but it's not too bad either.






      share|improve this answer


























      • IMHO it's nicer than an accepted method

        – Andrzej Martyna
        Oct 24 '17 at 13:13











      • Still not as efficient as PHP doest it.

        – Digital Human
        Jan 11 '18 at 7:15



















      2














      Traits can be implemented in C# 8 by using default interface methods. Java 8 introduced default interface methods for this reason too.



      Using C# 8, you can write almost exactly what you proposed in the question. The traits are implemented by the IClientWeight, IClientHeight interfaces that provide a default implementation for their methods. In this case, they just return 0:



      public interface IClientWeight
      {
      int getWeight()=>0;
      }

      public interface IClientHeight
      {
      int getHeight()=>0;
      }

      public class Client
      {
      public String Name {get;set;}
      }


      ClientA and ClientB have the traits but don't implement them. ClientC implements only IClientHeight and returns a different number, in this case 16 :



      class ClientA : Client, IClientWeight{}
      class ClientB : Client, IClientHeight{}
      class ClientC : Client, IClientWeight, IClientHeight
      {
      public int getHeight()=>16;
      }


      When getHeight() is called in ClientB through the interface, the default implementation is called. getHeight() can only be called through the interface.



      ClientC implements the IClientHeight interface so its own method is called. The method is available through the class itself.



      public class C {
      public void M() {
      //Accessed through the interface
      IClientHeight clientB=new ClientB();
      clientB.getHeight();

      //Accessed directly or through the interface
      var clientC=new ClientC();
      clientC.getHeight();
      }
      }


      This SharpLab.io example shows the code produced from this example



      Many of the traits features described in the PHP overview on traits can be implemented easily with default interface methods. Traits (interfaces) can be combined. It's also possible to define abstract methods to force classes to implement certain requirements.



      Let's say we want our traits to have sayHeight() and sayWeight() methods that return a string with the height or weight. They'd need some way to force exhibiting classes (term stolen from the PHP guide) to implement a method that returns the height and weight :



      public interface IClientWeight
      {
      abstract int getWeight();
      String sayWeight()=>getWeight().ToString();
      }

      public interface IClientHeight
      {
      abstract int getHeight();
      String sayHeight()=>getHeight().ToString();
      }

      //Combines both traits
      public interface IClientBoth:IClientHeight,IClientWeight{}


      The clients now have to implement thet getHeight() or getWeight() method but don't need to know anything about the say methods.



      This offers a cleaner way to decorate



      SharpLab.io link for this sample.






      share|improve this answer

































        0














        This sounds like PHP's version of Aspect Oriented Programming. There are tools to help like PostSharp or MS Unity in some cases. If you want to roll-your-own, code-injection using C# Attributes is one approach, or as suggested extension methods for limited cases.



        Really depends how complicated you want to get. If you are trying to build something complex I'd be looking at some of these tools to help.






        share|improve this answer
























        • Does AoP/PostSharp/Unity allow adding new members that become part of the static type system? (My limited AoP experience was just with annotation cut-points and similar..)

          – user166390
          May 24 '12 at 0:03













        • PostSharp rewrites the IL code and should be able to do that, yes.

          – Lucero
          May 24 '12 at 0:15











        • Yes I believe so, via aspects for member/interface introduction (at the IL level as noted). My experience is limited also, but I've not had much practical opportunity to get too deep into this approach.

          – RJ Lohan
          May 24 '12 at 0:38











        Your Answer






        StackExchange.ifUsing("editor", function () {
        StackExchange.using("externalEditor", function () {
        StackExchange.using("snippets", function () {
        StackExchange.snippets.init();
        });
        });
        }, "code-snippets");

        StackExchange.ready(function() {
        var channelOptions = {
        tags: "".split(" "),
        id: "1"
        };
        initTagRenderer("".split(" "), "".split(" "), channelOptions);

        StackExchange.using("externalEditor", function() {
        // Have to fire editor after snippets, if snippets enabled
        if (StackExchange.settings.snippets.snippetsEnabled) {
        StackExchange.using("snippets", function() {
        createEditor();
        });
        }
        else {
        createEditor();
        }
        });

        function createEditor() {
        StackExchange.prepareEditor({
        heartbeatType: 'answer',
        autoActivateHeartbeat: false,
        convertImagesToLinks: true,
        noModals: true,
        showLowRepImageUploadWarning: true,
        reputationToPostImages: 10,
        bindNavPrevention: true,
        postfix: "",
        imageUploader: {
        brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
        contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
        allowUrls: true
        },
        onDemand: true,
        discardSelector: ".discard-answer"
        ,immediatelyShowMarkdownHelp:true
        });


        }
        });














        draft saved

        draft discarded


















        StackExchange.ready(
        function () {
        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f10729230%2fhow-would-you-implement-a-trait-design-pattern-in-c%23new-answer', 'question_page');
        }
        );

        Post as a guest















        Required, but never shown

























        8 Answers
        8






        active

        oldest

        votes








        8 Answers
        8






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes









        45














        You can get the syntax by using marker interfaces and extension methods.



        Prerequisite: the interfaces need to define the contract which is later used by the extension method. Basically the interface defines the contract for being able to "implement" a trait; ideally the class where you add the interface should already have all members of the interface present so that no additional implementation is required.



        public class Client {
        public double Weight { get; }

        public double Height { get; }
        }

        public interface TClientWeight {
        double Weight { get; }
        }

        public interface TClientHeight {
        double Height { get; }
        }

        public class ClientA: Client, TClientWeight { }

        public class ClientB: Client, TClientHeight { }

        public class ClientC: Client, TClientWeight, TClientHeight { }

        public static class TClientWeightMethods {
        public static bool IsHeavierThan(this TClientWeight client, double weight) {
        return client.Weight > weight;
        }
        // add more methods as you see fit
        }

        public static class TClientHeightMethods {
        public static bool IsTallerThan(this TClientHeight client, double height) {
        return client.Height > height;
        }
        // add more methods as you see fit
        }


        Use like this:



        var ca = new ClientA();
        ca.IsHeavierThan(10); // OK
        ca.IsTallerThan(10); // compiler error


        Edit: The question was raised how additional data could be stored. This can also be addressed by doing some extra coding:



        public interface IDynamicObject {
        bool TryGetAttribute(string key, out object value);
        void SetAttribute(string key, object value);
        // void RemoveAttribute(string key)
        }

        public class DynamicObject: IDynamicObject {
        private readonly Dictionary<string, object> data = new Dictionary<string, object>(StringComparer.Ordinal);

        bool IDynamicObject.TryGetAttribute(string key, out object value) {
        return data.TryGet(key, out value);
        }

        void IDynamicObject.SetAttribute(string key, object value) {
        data[key] = value;
        }
        }


        And then, the trait methods can add and retrieve data if the "trait interface" inherits from IDynamicObject:



        public class Client: DynamicObject { /* implementation see above */ }

        public interface TClientWeight, IDynamicObject {
        double Weight { get; }
        }

        public class ClientA: Client, TClientWeight { }

        public static class TClientWeightMethods {
        public static bool HasWeightChanged(this TClientWeight client) {
        object oldWeight;
        bool result = client.TryGetAttribute("oldWeight", out oldWeight) && client.Weight.Equals(oldWeight);
        client.SetAttribute("oldWeight", client.Weight);
        return result;
        }
        // add more methods as you see fit
        }


        Note: by implementing IDynamicMetaObjectProvider as well the object would even allow to expose the dynamic data through the DLR, making the access to the additional properties transparent when used with the dynamic keyword.






        share|improve this answer





















        • 5





          So you're saying put all the data in the base class, and all the method implementations in extension methods that have hooks on the interfaces? It's curious solution, but perhaps workable. My only beef is that you're making the client classes carry a lot of "dead weight" (unused members). With some fancy serialization it won't need to be saved to disk, but it's still consuming memory.

          – mpen
          May 23 '12 at 23:46











        • "Sort of". I sure can't think of anything better within the C# language, so +1. I do not give this the same footing as a Trait, however. (A sever limitation is outlined by Mark.)

          – user166390
          May 23 '12 at 23:46













        • Err.. I guess with C# properties I only have to implement the property for each derived class and I can store the data there. It's a little bit redundant, but I guess it's better than re-implementing all the methods too.

          – mpen
          May 23 '12 at 23:48











        • To complete this answer, I'd still like to see you define a concrete member variable (all I see is properties). I'm not sure if you intend for me to define them in Client, or redefine them multiple times in ClientB and ClientC as needed.

          – mpen
          May 23 '12 at 23:58






        • 1





          @Mark, see my updates for dynamic data storage (implementing the serialization is left as an excercise to the reader ;) ). Since interfaces cannot define contracts for fields you cannot use fields as part of the "trait", but of course the properties can be read-write! I'm not saying that C# has traits, but rather that the extension methods can serve as reusable code blocks for interfaces, so that re-implementation of the methods is not required; of course the code has to have all needed members readily available on the interface.

          – Lucero
          May 24 '12 at 0:07


















        45














        You can get the syntax by using marker interfaces and extension methods.



        Prerequisite: the interfaces need to define the contract which is later used by the extension method. Basically the interface defines the contract for being able to "implement" a trait; ideally the class where you add the interface should already have all members of the interface present so that no additional implementation is required.



        public class Client {
        public double Weight { get; }

        public double Height { get; }
        }

        public interface TClientWeight {
        double Weight { get; }
        }

        public interface TClientHeight {
        double Height { get; }
        }

        public class ClientA: Client, TClientWeight { }

        public class ClientB: Client, TClientHeight { }

        public class ClientC: Client, TClientWeight, TClientHeight { }

        public static class TClientWeightMethods {
        public static bool IsHeavierThan(this TClientWeight client, double weight) {
        return client.Weight > weight;
        }
        // add more methods as you see fit
        }

        public static class TClientHeightMethods {
        public static bool IsTallerThan(this TClientHeight client, double height) {
        return client.Height > height;
        }
        // add more methods as you see fit
        }


        Use like this:



        var ca = new ClientA();
        ca.IsHeavierThan(10); // OK
        ca.IsTallerThan(10); // compiler error


        Edit: The question was raised how additional data could be stored. This can also be addressed by doing some extra coding:



        public interface IDynamicObject {
        bool TryGetAttribute(string key, out object value);
        void SetAttribute(string key, object value);
        // void RemoveAttribute(string key)
        }

        public class DynamicObject: IDynamicObject {
        private readonly Dictionary<string, object> data = new Dictionary<string, object>(StringComparer.Ordinal);

        bool IDynamicObject.TryGetAttribute(string key, out object value) {
        return data.TryGet(key, out value);
        }

        void IDynamicObject.SetAttribute(string key, object value) {
        data[key] = value;
        }
        }


        And then, the trait methods can add and retrieve data if the "trait interface" inherits from IDynamicObject:



        public class Client: DynamicObject { /* implementation see above */ }

        public interface TClientWeight, IDynamicObject {
        double Weight { get; }
        }

        public class ClientA: Client, TClientWeight { }

        public static class TClientWeightMethods {
        public static bool HasWeightChanged(this TClientWeight client) {
        object oldWeight;
        bool result = client.TryGetAttribute("oldWeight", out oldWeight) && client.Weight.Equals(oldWeight);
        client.SetAttribute("oldWeight", client.Weight);
        return result;
        }
        // add more methods as you see fit
        }


        Note: by implementing IDynamicMetaObjectProvider as well the object would even allow to expose the dynamic data through the DLR, making the access to the additional properties transparent when used with the dynamic keyword.






        share|improve this answer





















        • 5





          So you're saying put all the data in the base class, and all the method implementations in extension methods that have hooks on the interfaces? It's curious solution, but perhaps workable. My only beef is that you're making the client classes carry a lot of "dead weight" (unused members). With some fancy serialization it won't need to be saved to disk, but it's still consuming memory.

          – mpen
          May 23 '12 at 23:46











        • "Sort of". I sure can't think of anything better within the C# language, so +1. I do not give this the same footing as a Trait, however. (A sever limitation is outlined by Mark.)

          – user166390
          May 23 '12 at 23:46













        • Err.. I guess with C# properties I only have to implement the property for each derived class and I can store the data there. It's a little bit redundant, but I guess it's better than re-implementing all the methods too.

          – mpen
          May 23 '12 at 23:48











        • To complete this answer, I'd still like to see you define a concrete member variable (all I see is properties). I'm not sure if you intend for me to define them in Client, or redefine them multiple times in ClientB and ClientC as needed.

          – mpen
          May 23 '12 at 23:58






        • 1





          @Mark, see my updates for dynamic data storage (implementing the serialization is left as an excercise to the reader ;) ). Since interfaces cannot define contracts for fields you cannot use fields as part of the "trait", but of course the properties can be read-write! I'm not saying that C# has traits, but rather that the extension methods can serve as reusable code blocks for interfaces, so that re-implementation of the methods is not required; of course the code has to have all needed members readily available on the interface.

          – Lucero
          May 24 '12 at 0:07
















        45












        45








        45







        You can get the syntax by using marker interfaces and extension methods.



        Prerequisite: the interfaces need to define the contract which is later used by the extension method. Basically the interface defines the contract for being able to "implement" a trait; ideally the class where you add the interface should already have all members of the interface present so that no additional implementation is required.



        public class Client {
        public double Weight { get; }

        public double Height { get; }
        }

        public interface TClientWeight {
        double Weight { get; }
        }

        public interface TClientHeight {
        double Height { get; }
        }

        public class ClientA: Client, TClientWeight { }

        public class ClientB: Client, TClientHeight { }

        public class ClientC: Client, TClientWeight, TClientHeight { }

        public static class TClientWeightMethods {
        public static bool IsHeavierThan(this TClientWeight client, double weight) {
        return client.Weight > weight;
        }
        // add more methods as you see fit
        }

        public static class TClientHeightMethods {
        public static bool IsTallerThan(this TClientHeight client, double height) {
        return client.Height > height;
        }
        // add more methods as you see fit
        }


        Use like this:



        var ca = new ClientA();
        ca.IsHeavierThan(10); // OK
        ca.IsTallerThan(10); // compiler error


        Edit: The question was raised how additional data could be stored. This can also be addressed by doing some extra coding:



        public interface IDynamicObject {
        bool TryGetAttribute(string key, out object value);
        void SetAttribute(string key, object value);
        // void RemoveAttribute(string key)
        }

        public class DynamicObject: IDynamicObject {
        private readonly Dictionary<string, object> data = new Dictionary<string, object>(StringComparer.Ordinal);

        bool IDynamicObject.TryGetAttribute(string key, out object value) {
        return data.TryGet(key, out value);
        }

        void IDynamicObject.SetAttribute(string key, object value) {
        data[key] = value;
        }
        }


        And then, the trait methods can add and retrieve data if the "trait interface" inherits from IDynamicObject:



        public class Client: DynamicObject { /* implementation see above */ }

        public interface TClientWeight, IDynamicObject {
        double Weight { get; }
        }

        public class ClientA: Client, TClientWeight { }

        public static class TClientWeightMethods {
        public static bool HasWeightChanged(this TClientWeight client) {
        object oldWeight;
        bool result = client.TryGetAttribute("oldWeight", out oldWeight) && client.Weight.Equals(oldWeight);
        client.SetAttribute("oldWeight", client.Weight);
        return result;
        }
        // add more methods as you see fit
        }


        Note: by implementing IDynamicMetaObjectProvider as well the object would even allow to expose the dynamic data through the DLR, making the access to the additional properties transparent when used with the dynamic keyword.






        share|improve this answer















        You can get the syntax by using marker interfaces and extension methods.



        Prerequisite: the interfaces need to define the contract which is later used by the extension method. Basically the interface defines the contract for being able to "implement" a trait; ideally the class where you add the interface should already have all members of the interface present so that no additional implementation is required.



        public class Client {
        public double Weight { get; }

        public double Height { get; }
        }

        public interface TClientWeight {
        double Weight { get; }
        }

        public interface TClientHeight {
        double Height { get; }
        }

        public class ClientA: Client, TClientWeight { }

        public class ClientB: Client, TClientHeight { }

        public class ClientC: Client, TClientWeight, TClientHeight { }

        public static class TClientWeightMethods {
        public static bool IsHeavierThan(this TClientWeight client, double weight) {
        return client.Weight > weight;
        }
        // add more methods as you see fit
        }

        public static class TClientHeightMethods {
        public static bool IsTallerThan(this TClientHeight client, double height) {
        return client.Height > height;
        }
        // add more methods as you see fit
        }


        Use like this:



        var ca = new ClientA();
        ca.IsHeavierThan(10); // OK
        ca.IsTallerThan(10); // compiler error


        Edit: The question was raised how additional data could be stored. This can also be addressed by doing some extra coding:



        public interface IDynamicObject {
        bool TryGetAttribute(string key, out object value);
        void SetAttribute(string key, object value);
        // void RemoveAttribute(string key)
        }

        public class DynamicObject: IDynamicObject {
        private readonly Dictionary<string, object> data = new Dictionary<string, object>(StringComparer.Ordinal);

        bool IDynamicObject.TryGetAttribute(string key, out object value) {
        return data.TryGet(key, out value);
        }

        void IDynamicObject.SetAttribute(string key, object value) {
        data[key] = value;
        }
        }


        And then, the trait methods can add and retrieve data if the "trait interface" inherits from IDynamicObject:



        public class Client: DynamicObject { /* implementation see above */ }

        public interface TClientWeight, IDynamicObject {
        double Weight { get; }
        }

        public class ClientA: Client, TClientWeight { }

        public static class TClientWeightMethods {
        public static bool HasWeightChanged(this TClientWeight client) {
        object oldWeight;
        bool result = client.TryGetAttribute("oldWeight", out oldWeight) && client.Weight.Equals(oldWeight);
        client.SetAttribute("oldWeight", client.Weight);
        return result;
        }
        // add more methods as you see fit
        }


        Note: by implementing IDynamicMetaObjectProvider as well the object would even allow to expose the dynamic data through the DLR, making the access to the additional properties transparent when used with the dynamic keyword.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Oct 5 '14 at 22:55

























        answered May 23 '12 at 23:36









        LuceroLucero

        52k593142




        52k593142








        • 5





          So you're saying put all the data in the base class, and all the method implementations in extension methods that have hooks on the interfaces? It's curious solution, but perhaps workable. My only beef is that you're making the client classes carry a lot of "dead weight" (unused members). With some fancy serialization it won't need to be saved to disk, but it's still consuming memory.

          – mpen
          May 23 '12 at 23:46











        • "Sort of". I sure can't think of anything better within the C# language, so +1. I do not give this the same footing as a Trait, however. (A sever limitation is outlined by Mark.)

          – user166390
          May 23 '12 at 23:46













        • Err.. I guess with C# properties I only have to implement the property for each derived class and I can store the data there. It's a little bit redundant, but I guess it's better than re-implementing all the methods too.

          – mpen
          May 23 '12 at 23:48











        • To complete this answer, I'd still like to see you define a concrete member variable (all I see is properties). I'm not sure if you intend for me to define them in Client, or redefine them multiple times in ClientB and ClientC as needed.

          – mpen
          May 23 '12 at 23:58






        • 1





          @Mark, see my updates for dynamic data storage (implementing the serialization is left as an excercise to the reader ;) ). Since interfaces cannot define contracts for fields you cannot use fields as part of the "trait", but of course the properties can be read-write! I'm not saying that C# has traits, but rather that the extension methods can serve as reusable code blocks for interfaces, so that re-implementation of the methods is not required; of course the code has to have all needed members readily available on the interface.

          – Lucero
          May 24 '12 at 0:07
















        • 5





          So you're saying put all the data in the base class, and all the method implementations in extension methods that have hooks on the interfaces? It's curious solution, but perhaps workable. My only beef is that you're making the client classes carry a lot of "dead weight" (unused members). With some fancy serialization it won't need to be saved to disk, but it's still consuming memory.

          – mpen
          May 23 '12 at 23:46











        • "Sort of". I sure can't think of anything better within the C# language, so +1. I do not give this the same footing as a Trait, however. (A sever limitation is outlined by Mark.)

          – user166390
          May 23 '12 at 23:46













        • Err.. I guess with C# properties I only have to implement the property for each derived class and I can store the data there. It's a little bit redundant, but I guess it's better than re-implementing all the methods too.

          – mpen
          May 23 '12 at 23:48











        • To complete this answer, I'd still like to see you define a concrete member variable (all I see is properties). I'm not sure if you intend for me to define them in Client, or redefine them multiple times in ClientB and ClientC as needed.

          – mpen
          May 23 '12 at 23:58






        • 1





          @Mark, see my updates for dynamic data storage (implementing the serialization is left as an excercise to the reader ;) ). Since interfaces cannot define contracts for fields you cannot use fields as part of the "trait", but of course the properties can be read-write! I'm not saying that C# has traits, but rather that the extension methods can serve as reusable code blocks for interfaces, so that re-implementation of the methods is not required; of course the code has to have all needed members readily available on the interface.

          – Lucero
          May 24 '12 at 0:07










        5




        5





        So you're saying put all the data in the base class, and all the method implementations in extension methods that have hooks on the interfaces? It's curious solution, but perhaps workable. My only beef is that you're making the client classes carry a lot of "dead weight" (unused members). With some fancy serialization it won't need to be saved to disk, but it's still consuming memory.

        – mpen
        May 23 '12 at 23:46





        So you're saying put all the data in the base class, and all the method implementations in extension methods that have hooks on the interfaces? It's curious solution, but perhaps workable. My only beef is that you're making the client classes carry a lot of "dead weight" (unused members). With some fancy serialization it won't need to be saved to disk, but it's still consuming memory.

        – mpen
        May 23 '12 at 23:46













        "Sort of". I sure can't think of anything better within the C# language, so +1. I do not give this the same footing as a Trait, however. (A sever limitation is outlined by Mark.)

        – user166390
        May 23 '12 at 23:46







        "Sort of". I sure can't think of anything better within the C# language, so +1. I do not give this the same footing as a Trait, however. (A sever limitation is outlined by Mark.)

        – user166390
        May 23 '12 at 23:46















        Err.. I guess with C# properties I only have to implement the property for each derived class and I can store the data there. It's a little bit redundant, but I guess it's better than re-implementing all the methods too.

        – mpen
        May 23 '12 at 23:48





        Err.. I guess with C# properties I only have to implement the property for each derived class and I can store the data there. It's a little bit redundant, but I guess it's better than re-implementing all the methods too.

        – mpen
        May 23 '12 at 23:48













        To complete this answer, I'd still like to see you define a concrete member variable (all I see is properties). I'm not sure if you intend for me to define them in Client, or redefine them multiple times in ClientB and ClientC as needed.

        – mpen
        May 23 '12 at 23:58





        To complete this answer, I'd still like to see you define a concrete member variable (all I see is properties). I'm not sure if you intend for me to define them in Client, or redefine them multiple times in ClientB and ClientC as needed.

        – mpen
        May 23 '12 at 23:58




        1




        1





        @Mark, see my updates for dynamic data storage (implementing the serialization is left as an excercise to the reader ;) ). Since interfaces cannot define contracts for fields you cannot use fields as part of the "trait", but of course the properties can be read-write! I'm not saying that C# has traits, but rather that the extension methods can serve as reusable code blocks for interfaces, so that re-implementation of the methods is not required; of course the code has to have all needed members readily available on the interface.

        – Lucero
        May 24 '12 at 0:07







        @Mark, see my updates for dynamic data storage (implementing the serialization is left as an excercise to the reader ;) ). Since interfaces cannot define contracts for fields you cannot use fields as part of the "trait", but of course the properties can be read-write! I'm not saying that C# has traits, but rather that the extension methods can serve as reusable code blocks for interfaces, so that re-implementation of the methods is not required; of course the code has to have all needed members readily available on the interface.

        – Lucero
        May 24 '12 at 0:07















        8














        C# language (at least to version 5) does not have support for Traits.



        However, Scala has Traits and Scala runs on the JVM (and CLR). Therefore, it's not a matter of run-time, but simply that of the language.



        Consider that Traits, at least at the Scala sense, can be thought of as "pretty magic to compile in proxy methods" (they do not affect the MRO, which is different from Mixins in Ruby). In C# the way to get this behavior would be to use interfaces and "lots of manual proxy methods" (e.g. composition).



        This tedious process could be done with a hypothetical processor (perhaps automatic code generation for a partial class via templates?), but that's not C#.



        Happy coding.






        share|improve this answer


























        • I'm not exactly sure what this answers. Are you suggesting that I should hack together something to pre-process my C# code?

          – mpen
          May 23 '12 at 23:32











        • @Mark No. I was 1) Suggesting C#, the language, cannot support it (although perhaps with dynamic proxies? This level of magic is beyond me.) 2) That Traits do not affect the MRO and can be "simulated by hand"; that is, a Trait can be flattened into every Class it is mixed into, as with Composition.

          – user166390
          May 23 '12 at 23:33








        • 1





          @Mark Ahh, Method Resolution Order. That is, Traits (again, in the Scala sense which are still based on Single Inheritance run-time) do not actually affect the class hierarchy. There is no "trait class" added to the [virtual] dispatch tables. The methods/properties in the Traits are copied (during completing) into the respective classes. Here is are some papers about traits as used in Scala. Ordersky presents that Traits can be used in a SI runtime, which is why they are "baked in" at compilation.

          – user166390
          May 23 '12 at 23:38








        • 1





          @Mark This differs from a language like Ruby which will inject the "mixin" type (a form of traits) into the MRO (which is a form of alternating the class hierarchy, but with control and restrictions).

          – user166390
          May 23 '12 at 23:43








        • 2





          I'm hesitant to upvote you because you haven't provided me with anything concrete yet, just a lot of talk about other languages. I'm trying to figure out how I can borrow some of these ideas from Scala....but that's all built-in to the language. How's it transferable?

          – mpen
          May 23 '12 at 23:50
















        8














        C# language (at least to version 5) does not have support for Traits.



        However, Scala has Traits and Scala runs on the JVM (and CLR). Therefore, it's not a matter of run-time, but simply that of the language.



        Consider that Traits, at least at the Scala sense, can be thought of as "pretty magic to compile in proxy methods" (they do not affect the MRO, which is different from Mixins in Ruby). In C# the way to get this behavior would be to use interfaces and "lots of manual proxy methods" (e.g. composition).



        This tedious process could be done with a hypothetical processor (perhaps automatic code generation for a partial class via templates?), but that's not C#.



        Happy coding.






        share|improve this answer


























        • I'm not exactly sure what this answers. Are you suggesting that I should hack together something to pre-process my C# code?

          – mpen
          May 23 '12 at 23:32











        • @Mark No. I was 1) Suggesting C#, the language, cannot support it (although perhaps with dynamic proxies? This level of magic is beyond me.) 2) That Traits do not affect the MRO and can be "simulated by hand"; that is, a Trait can be flattened into every Class it is mixed into, as with Composition.

          – user166390
          May 23 '12 at 23:33








        • 1





          @Mark Ahh, Method Resolution Order. That is, Traits (again, in the Scala sense which are still based on Single Inheritance run-time) do not actually affect the class hierarchy. There is no "trait class" added to the [virtual] dispatch tables. The methods/properties in the Traits are copied (during completing) into the respective classes. Here is are some papers about traits as used in Scala. Ordersky presents that Traits can be used in a SI runtime, which is why they are "baked in" at compilation.

          – user166390
          May 23 '12 at 23:38








        • 1





          @Mark This differs from a language like Ruby which will inject the "mixin" type (a form of traits) into the MRO (which is a form of alternating the class hierarchy, but with control and restrictions).

          – user166390
          May 23 '12 at 23:43








        • 2





          I'm hesitant to upvote you because you haven't provided me with anything concrete yet, just a lot of talk about other languages. I'm trying to figure out how I can borrow some of these ideas from Scala....but that's all built-in to the language. How's it transferable?

          – mpen
          May 23 '12 at 23:50














        8












        8








        8







        C# language (at least to version 5) does not have support for Traits.



        However, Scala has Traits and Scala runs on the JVM (and CLR). Therefore, it's not a matter of run-time, but simply that of the language.



        Consider that Traits, at least at the Scala sense, can be thought of as "pretty magic to compile in proxy methods" (they do not affect the MRO, which is different from Mixins in Ruby). In C# the way to get this behavior would be to use interfaces and "lots of manual proxy methods" (e.g. composition).



        This tedious process could be done with a hypothetical processor (perhaps automatic code generation for a partial class via templates?), but that's not C#.



        Happy coding.






        share|improve this answer















        C# language (at least to version 5) does not have support for Traits.



        However, Scala has Traits and Scala runs on the JVM (and CLR). Therefore, it's not a matter of run-time, but simply that of the language.



        Consider that Traits, at least at the Scala sense, can be thought of as "pretty magic to compile in proxy methods" (they do not affect the MRO, which is different from Mixins in Ruby). In C# the way to get this behavior would be to use interfaces and "lots of manual proxy methods" (e.g. composition).



        This tedious process could be done with a hypothetical processor (perhaps automatic code generation for a partial class via templates?), but that's not C#.



        Happy coding.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited May 23 '12 at 23:45

























        answered May 23 '12 at 23:30







        user166390




















        • I'm not exactly sure what this answers. Are you suggesting that I should hack together something to pre-process my C# code?

          – mpen
          May 23 '12 at 23:32











        • @Mark No. I was 1) Suggesting C#, the language, cannot support it (although perhaps with dynamic proxies? This level of magic is beyond me.) 2) That Traits do not affect the MRO and can be "simulated by hand"; that is, a Trait can be flattened into every Class it is mixed into, as with Composition.

          – user166390
          May 23 '12 at 23:33








        • 1





          @Mark Ahh, Method Resolution Order. That is, Traits (again, in the Scala sense which are still based on Single Inheritance run-time) do not actually affect the class hierarchy. There is no "trait class" added to the [virtual] dispatch tables. The methods/properties in the Traits are copied (during completing) into the respective classes. Here is are some papers about traits as used in Scala. Ordersky presents that Traits can be used in a SI runtime, which is why they are "baked in" at compilation.

          – user166390
          May 23 '12 at 23:38








        • 1





          @Mark This differs from a language like Ruby which will inject the "mixin" type (a form of traits) into the MRO (which is a form of alternating the class hierarchy, but with control and restrictions).

          – user166390
          May 23 '12 at 23:43








        • 2





          I'm hesitant to upvote you because you haven't provided me with anything concrete yet, just a lot of talk about other languages. I'm trying to figure out how I can borrow some of these ideas from Scala....but that's all built-in to the language. How's it transferable?

          – mpen
          May 23 '12 at 23:50



















        • I'm not exactly sure what this answers. Are you suggesting that I should hack together something to pre-process my C# code?

          – mpen
          May 23 '12 at 23:32











        • @Mark No. I was 1) Suggesting C#, the language, cannot support it (although perhaps with dynamic proxies? This level of magic is beyond me.) 2) That Traits do not affect the MRO and can be "simulated by hand"; that is, a Trait can be flattened into every Class it is mixed into, as with Composition.

          – user166390
          May 23 '12 at 23:33








        • 1





          @Mark Ahh, Method Resolution Order. That is, Traits (again, in the Scala sense which are still based on Single Inheritance run-time) do not actually affect the class hierarchy. There is no "trait class" added to the [virtual] dispatch tables. The methods/properties in the Traits are copied (during completing) into the respective classes. Here is are some papers about traits as used in Scala. Ordersky presents that Traits can be used in a SI runtime, which is why they are "baked in" at compilation.

          – user166390
          May 23 '12 at 23:38








        • 1





          @Mark This differs from a language like Ruby which will inject the "mixin" type (a form of traits) into the MRO (which is a form of alternating the class hierarchy, but with control and restrictions).

          – user166390
          May 23 '12 at 23:43








        • 2





          I'm hesitant to upvote you because you haven't provided me with anything concrete yet, just a lot of talk about other languages. I'm trying to figure out how I can borrow some of these ideas from Scala....but that's all built-in to the language. How's it transferable?

          – mpen
          May 23 '12 at 23:50

















        I'm not exactly sure what this answers. Are you suggesting that I should hack together something to pre-process my C# code?

        – mpen
        May 23 '12 at 23:32





        I'm not exactly sure what this answers. Are you suggesting that I should hack together something to pre-process my C# code?

        – mpen
        May 23 '12 at 23:32













        @Mark No. I was 1) Suggesting C#, the language, cannot support it (although perhaps with dynamic proxies? This level of magic is beyond me.) 2) That Traits do not affect the MRO and can be "simulated by hand"; that is, a Trait can be flattened into every Class it is mixed into, as with Composition.

        – user166390
        May 23 '12 at 23:33







        @Mark No. I was 1) Suggesting C#, the language, cannot support it (although perhaps with dynamic proxies? This level of magic is beyond me.) 2) That Traits do not affect the MRO and can be "simulated by hand"; that is, a Trait can be flattened into every Class it is mixed into, as with Composition.

        – user166390
        May 23 '12 at 23:33






        1




        1





        @Mark Ahh, Method Resolution Order. That is, Traits (again, in the Scala sense which are still based on Single Inheritance run-time) do not actually affect the class hierarchy. There is no "trait class" added to the [virtual] dispatch tables. The methods/properties in the Traits are copied (during completing) into the respective classes. Here is are some papers about traits as used in Scala. Ordersky presents that Traits can be used in a SI runtime, which is why they are "baked in" at compilation.

        – user166390
        May 23 '12 at 23:38







        @Mark Ahh, Method Resolution Order. That is, Traits (again, in the Scala sense which are still based on Single Inheritance run-time) do not actually affect the class hierarchy. There is no "trait class" added to the [virtual] dispatch tables. The methods/properties in the Traits are copied (during completing) into the respective classes. Here is are some papers about traits as used in Scala. Ordersky presents that Traits can be used in a SI runtime, which is why they are "baked in" at compilation.

        – user166390
        May 23 '12 at 23:38






        1




        1





        @Mark This differs from a language like Ruby which will inject the "mixin" type (a form of traits) into the MRO (which is a form of alternating the class hierarchy, but with control and restrictions).

        – user166390
        May 23 '12 at 23:43







        @Mark This differs from a language like Ruby which will inject the "mixin" type (a form of traits) into the MRO (which is a form of alternating the class hierarchy, but with control and restrictions).

        – user166390
        May 23 '12 at 23:43






        2




        2





        I'm hesitant to upvote you because you haven't provided me with anything concrete yet, just a lot of talk about other languages. I'm trying to figure out how I can borrow some of these ideas from Scala....but that's all built-in to the language. How's it transferable?

        – mpen
        May 23 '12 at 23:50





        I'm hesitant to upvote you because you haven't provided me with anything concrete yet, just a lot of talk about other languages. I'm trying to figure out how I can borrow some of these ideas from Scala....but that's all built-in to the language. How's it transferable?

        – mpen
        May 23 '12 at 23:50











        5














        I'd like to point to NRoles, an experiment with roles in C#, where roles are similar to traits.



        NRoles uses a post-compiler to rewrite the IL and inject the methods into a class. This allows you to write code like that:



        public class RSwitchable : Role
        {
        private bool on = false;
        public void TurnOn() { on = true; }
        public void TurnOff() { on = false; }
        public bool IsOn { get { return on; } }
        public bool IsOff { get { return !on; } }
        }

        public class RTunable : Role
        {
        public int Channel { get; private set; }
        public void Seek(int step) { Channel += step; }
        }

        public class Radio : Does<RSwitchable>, Does<RTunable> { }


        where class Radio implements RSwitchable and RTunable. Behind the scenes, Does<R> is an interface with no members, so basically Radio compiles to an empty class. The post-compilation IL rewriting injects the methods of RSwitchable and RTunable into Radio, which can then be used as if it really derived from the two roles (from another assembly):



        var radio = new Radio();
        radio.TurnOn();
        radio.Seek(42);


        To use radio directly before rewriting happened (that is, in the same assembly as where the Radio type is declared), you have to resort to extensions methods As<R>():



        radio.As<RSwitchable>().TurnOn();
        radio.As<RTunable>().Seek(42);


        since the compiler would not allow to call TurnOn or Seek directly on the Radio class.






        share|improve this answer




























          5














          I'd like to point to NRoles, an experiment with roles in C#, where roles are similar to traits.



          NRoles uses a post-compiler to rewrite the IL and inject the methods into a class. This allows you to write code like that:



          public class RSwitchable : Role
          {
          private bool on = false;
          public void TurnOn() { on = true; }
          public void TurnOff() { on = false; }
          public bool IsOn { get { return on; } }
          public bool IsOff { get { return !on; } }
          }

          public class RTunable : Role
          {
          public int Channel { get; private set; }
          public void Seek(int step) { Channel += step; }
          }

          public class Radio : Does<RSwitchable>, Does<RTunable> { }


          where class Radio implements RSwitchable and RTunable. Behind the scenes, Does<R> is an interface with no members, so basically Radio compiles to an empty class. The post-compilation IL rewriting injects the methods of RSwitchable and RTunable into Radio, which can then be used as if it really derived from the two roles (from another assembly):



          var radio = new Radio();
          radio.TurnOn();
          radio.Seek(42);


          To use radio directly before rewriting happened (that is, in the same assembly as where the Radio type is declared), you have to resort to extensions methods As<R>():



          radio.As<RSwitchable>().TurnOn();
          radio.As<RTunable>().Seek(42);


          since the compiler would not allow to call TurnOn or Seek directly on the Radio class.






          share|improve this answer


























            5












            5








            5







            I'd like to point to NRoles, an experiment with roles in C#, where roles are similar to traits.



            NRoles uses a post-compiler to rewrite the IL and inject the methods into a class. This allows you to write code like that:



            public class RSwitchable : Role
            {
            private bool on = false;
            public void TurnOn() { on = true; }
            public void TurnOff() { on = false; }
            public bool IsOn { get { return on; } }
            public bool IsOff { get { return !on; } }
            }

            public class RTunable : Role
            {
            public int Channel { get; private set; }
            public void Seek(int step) { Channel += step; }
            }

            public class Radio : Does<RSwitchable>, Does<RTunable> { }


            where class Radio implements RSwitchable and RTunable. Behind the scenes, Does<R> is an interface with no members, so basically Radio compiles to an empty class. The post-compilation IL rewriting injects the methods of RSwitchable and RTunable into Radio, which can then be used as if it really derived from the two roles (from another assembly):



            var radio = new Radio();
            radio.TurnOn();
            radio.Seek(42);


            To use radio directly before rewriting happened (that is, in the same assembly as where the Radio type is declared), you have to resort to extensions methods As<R>():



            radio.As<RSwitchable>().TurnOn();
            radio.As<RTunable>().Seek(42);


            since the compiler would not allow to call TurnOn or Seek directly on the Radio class.






            share|improve this answer













            I'd like to point to NRoles, an experiment with roles in C#, where roles are similar to traits.



            NRoles uses a post-compiler to rewrite the IL and inject the methods into a class. This allows you to write code like that:



            public class RSwitchable : Role
            {
            private bool on = false;
            public void TurnOn() { on = true; }
            public void TurnOff() { on = false; }
            public bool IsOn { get { return on; } }
            public bool IsOff { get { return !on; } }
            }

            public class RTunable : Role
            {
            public int Channel { get; private set; }
            public void Seek(int step) { Channel += step; }
            }

            public class Radio : Does<RSwitchable>, Does<RTunable> { }


            where class Radio implements RSwitchable and RTunable. Behind the scenes, Does<R> is an interface with no members, so basically Radio compiles to an empty class. The post-compilation IL rewriting injects the methods of RSwitchable and RTunable into Radio, which can then be used as if it really derived from the two roles (from another assembly):



            var radio = new Radio();
            radio.TurnOn();
            radio.Seek(42);


            To use radio directly before rewriting happened (that is, in the same assembly as where the Radio type is declared), you have to resort to extensions methods As<R>():



            radio.As<RSwitchable>().TurnOn();
            radio.As<RTunable>().Seek(42);


            since the compiler would not allow to call TurnOn or Seek directly on the Radio class.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Sep 2 '14 at 9:09









            Pierre ArnaudPierre Arnaud

            6,35875899




            6,35875899























                5














                There is an academic project, developed by Stefan Reichart from the Software Composition Group at the University of Bern (Switzerland), which provides a true implementation of traits to the C# language.



                Have a look at the paper (PDF) on CSharpT for the full description of what he has done, based on the mono compiler.



                Here is a sample of what can be written:



                trait TCircle
                {
                public int Radius { get; set; }
                public int Surface { get { ... } }
                }

                trait TColor { ... }

                class MyCircle
                {
                uses { TCircle; TColor }
                }





                share|improve this answer




























                  5














                  There is an academic project, developed by Stefan Reichart from the Software Composition Group at the University of Bern (Switzerland), which provides a true implementation of traits to the C# language.



                  Have a look at the paper (PDF) on CSharpT for the full description of what he has done, based on the mono compiler.



                  Here is a sample of what can be written:



                  trait TCircle
                  {
                  public int Radius { get; set; }
                  public int Surface { get { ... } }
                  }

                  trait TColor { ... }

                  class MyCircle
                  {
                  uses { TCircle; TColor }
                  }





                  share|improve this answer


























                    5












                    5








                    5







                    There is an academic project, developed by Stefan Reichart from the Software Composition Group at the University of Bern (Switzerland), which provides a true implementation of traits to the C# language.



                    Have a look at the paper (PDF) on CSharpT for the full description of what he has done, based on the mono compiler.



                    Here is a sample of what can be written:



                    trait TCircle
                    {
                    public int Radius { get; set; }
                    public int Surface { get { ... } }
                    }

                    trait TColor { ... }

                    class MyCircle
                    {
                    uses { TCircle; TColor }
                    }





                    share|improve this answer













                    There is an academic project, developed by Stefan Reichart from the Software Composition Group at the University of Bern (Switzerland), which provides a true implementation of traits to the C# language.



                    Have a look at the paper (PDF) on CSharpT for the full description of what he has done, based on the mono compiler.



                    Here is a sample of what can be written:



                    trait TCircle
                    {
                    public int Radius { get; set; }
                    public int Surface { get { ... } }
                    }

                    trait TColor { ... }

                    class MyCircle
                    {
                    uses { TCircle; TColor }
                    }






                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Sep 2 '14 at 9:14









                    Pierre ArnaudPierre Arnaud

                    6,35875899




                    6,35875899























                        3














                        This is really an suggested extension to Lucero's answer where all the storage was in the base class.



                        How about using dependency properties for this?



                        This would have the effect of making the client classes light weight at run time when you have many properties that are not always set by every descendant. This is because the values are stored in a static member.



                        using System.Windows;

                        public class Client : DependencyObject
                        {
                        public string Name { get; set; }

                        public Client(string name)
                        {
                        Name = name;
                        }

                        //add to descendant to use
                        //public double Weight
                        //{
                        // get { return (double)GetValue(WeightProperty); }
                        // set { SetValue(WeightProperty, value); }
                        //}

                        public static readonly DependencyProperty WeightProperty =
                        DependencyProperty.Register("Weight", typeof(double), typeof(Client), new PropertyMetadata());


                        //add to descendant to use
                        //public double Height
                        //{
                        // get { return (double)GetValue(HeightProperty); }
                        // set { SetValue(HeightProperty, value); }
                        //}

                        public static readonly DependencyProperty HeightProperty =
                        DependencyProperty.Register("Height", typeof(double), typeof(Client), new PropertyMetadata());
                        }

                        public interface IWeight
                        {
                        double Weight { get; set; }
                        }

                        public interface IHeight
                        {
                        double Height { get; set; }
                        }

                        public class ClientA : Client, IWeight
                        {
                        public double Weight
                        {
                        get { return (double)GetValue(WeightProperty); }
                        set { SetValue(WeightProperty, value); }
                        }

                        public ClientA(string name, double weight)
                        : base(name)
                        {
                        Weight = weight;
                        }
                        }

                        public class ClientB : Client, IHeight
                        {
                        public double Height
                        {
                        get { return (double)GetValue(HeightProperty); }
                        set { SetValue(HeightProperty, value); }
                        }

                        public ClientB(string name, double height)
                        : base(name)
                        {
                        Height = height;
                        }
                        }

                        public class ClientC : Client, IHeight, IWeight
                        {
                        public double Height
                        {
                        get { return (double)GetValue(HeightProperty); }
                        set { SetValue(HeightProperty, value); }
                        }

                        public double Weight
                        {
                        get { return (double)GetValue(WeightProperty); }
                        set { SetValue(WeightProperty, value); }
                        }

                        public ClientC(string name, double weight, double height)
                        : base(name)
                        {
                        Weight = weight;
                        Height = height;
                        }

                        }

                        public static class ClientExt
                        {
                        public static double HeightInches(this IHeight client)
                        {
                        return client.Height * 39.3700787;
                        }

                        public static double WeightPounds(this IWeight client)
                        {
                        return client.Weight * 2.20462262;
                        }
                        }





                        share|improve this answer
























                        • Why should we possibly use WPF classes here?

                          – Javid
                          Dec 15 '17 at 7:07
















                        3














                        This is really an suggested extension to Lucero's answer where all the storage was in the base class.



                        How about using dependency properties for this?



                        This would have the effect of making the client classes light weight at run time when you have many properties that are not always set by every descendant. This is because the values are stored in a static member.



                        using System.Windows;

                        public class Client : DependencyObject
                        {
                        public string Name { get; set; }

                        public Client(string name)
                        {
                        Name = name;
                        }

                        //add to descendant to use
                        //public double Weight
                        //{
                        // get { return (double)GetValue(WeightProperty); }
                        // set { SetValue(WeightProperty, value); }
                        //}

                        public static readonly DependencyProperty WeightProperty =
                        DependencyProperty.Register("Weight", typeof(double), typeof(Client), new PropertyMetadata());


                        //add to descendant to use
                        //public double Height
                        //{
                        // get { return (double)GetValue(HeightProperty); }
                        // set { SetValue(HeightProperty, value); }
                        //}

                        public static readonly DependencyProperty HeightProperty =
                        DependencyProperty.Register("Height", typeof(double), typeof(Client), new PropertyMetadata());
                        }

                        public interface IWeight
                        {
                        double Weight { get; set; }
                        }

                        public interface IHeight
                        {
                        double Height { get; set; }
                        }

                        public class ClientA : Client, IWeight
                        {
                        public double Weight
                        {
                        get { return (double)GetValue(WeightProperty); }
                        set { SetValue(WeightProperty, value); }
                        }

                        public ClientA(string name, double weight)
                        : base(name)
                        {
                        Weight = weight;
                        }
                        }

                        public class ClientB : Client, IHeight
                        {
                        public double Height
                        {
                        get { return (double)GetValue(HeightProperty); }
                        set { SetValue(HeightProperty, value); }
                        }

                        public ClientB(string name, double height)
                        : base(name)
                        {
                        Height = height;
                        }
                        }

                        public class ClientC : Client, IHeight, IWeight
                        {
                        public double Height
                        {
                        get { return (double)GetValue(HeightProperty); }
                        set { SetValue(HeightProperty, value); }
                        }

                        public double Weight
                        {
                        get { return (double)GetValue(WeightProperty); }
                        set { SetValue(WeightProperty, value); }
                        }

                        public ClientC(string name, double weight, double height)
                        : base(name)
                        {
                        Weight = weight;
                        Height = height;
                        }

                        }

                        public static class ClientExt
                        {
                        public static double HeightInches(this IHeight client)
                        {
                        return client.Height * 39.3700787;
                        }

                        public static double WeightPounds(this IWeight client)
                        {
                        return client.Weight * 2.20462262;
                        }
                        }





                        share|improve this answer
























                        • Why should we possibly use WPF classes here?

                          – Javid
                          Dec 15 '17 at 7:07














                        3












                        3








                        3







                        This is really an suggested extension to Lucero's answer where all the storage was in the base class.



                        How about using dependency properties for this?



                        This would have the effect of making the client classes light weight at run time when you have many properties that are not always set by every descendant. This is because the values are stored in a static member.



                        using System.Windows;

                        public class Client : DependencyObject
                        {
                        public string Name { get; set; }

                        public Client(string name)
                        {
                        Name = name;
                        }

                        //add to descendant to use
                        //public double Weight
                        //{
                        // get { return (double)GetValue(WeightProperty); }
                        // set { SetValue(WeightProperty, value); }
                        //}

                        public static readonly DependencyProperty WeightProperty =
                        DependencyProperty.Register("Weight", typeof(double), typeof(Client), new PropertyMetadata());


                        //add to descendant to use
                        //public double Height
                        //{
                        // get { return (double)GetValue(HeightProperty); }
                        // set { SetValue(HeightProperty, value); }
                        //}

                        public static readonly DependencyProperty HeightProperty =
                        DependencyProperty.Register("Height", typeof(double), typeof(Client), new PropertyMetadata());
                        }

                        public interface IWeight
                        {
                        double Weight { get; set; }
                        }

                        public interface IHeight
                        {
                        double Height { get; set; }
                        }

                        public class ClientA : Client, IWeight
                        {
                        public double Weight
                        {
                        get { return (double)GetValue(WeightProperty); }
                        set { SetValue(WeightProperty, value); }
                        }

                        public ClientA(string name, double weight)
                        : base(name)
                        {
                        Weight = weight;
                        }
                        }

                        public class ClientB : Client, IHeight
                        {
                        public double Height
                        {
                        get { return (double)GetValue(HeightProperty); }
                        set { SetValue(HeightProperty, value); }
                        }

                        public ClientB(string name, double height)
                        : base(name)
                        {
                        Height = height;
                        }
                        }

                        public class ClientC : Client, IHeight, IWeight
                        {
                        public double Height
                        {
                        get { return (double)GetValue(HeightProperty); }
                        set { SetValue(HeightProperty, value); }
                        }

                        public double Weight
                        {
                        get { return (double)GetValue(WeightProperty); }
                        set { SetValue(WeightProperty, value); }
                        }

                        public ClientC(string name, double weight, double height)
                        : base(name)
                        {
                        Weight = weight;
                        Height = height;
                        }

                        }

                        public static class ClientExt
                        {
                        public static double HeightInches(this IHeight client)
                        {
                        return client.Height * 39.3700787;
                        }

                        public static double WeightPounds(this IWeight client)
                        {
                        return client.Weight * 2.20462262;
                        }
                        }





                        share|improve this answer













                        This is really an suggested extension to Lucero's answer where all the storage was in the base class.



                        How about using dependency properties for this?



                        This would have the effect of making the client classes light weight at run time when you have many properties that are not always set by every descendant. This is because the values are stored in a static member.



                        using System.Windows;

                        public class Client : DependencyObject
                        {
                        public string Name { get; set; }

                        public Client(string name)
                        {
                        Name = name;
                        }

                        //add to descendant to use
                        //public double Weight
                        //{
                        // get { return (double)GetValue(WeightProperty); }
                        // set { SetValue(WeightProperty, value); }
                        //}

                        public static readonly DependencyProperty WeightProperty =
                        DependencyProperty.Register("Weight", typeof(double), typeof(Client), new PropertyMetadata());


                        //add to descendant to use
                        //public double Height
                        //{
                        // get { return (double)GetValue(HeightProperty); }
                        // set { SetValue(HeightProperty, value); }
                        //}

                        public static readonly DependencyProperty HeightProperty =
                        DependencyProperty.Register("Height", typeof(double), typeof(Client), new PropertyMetadata());
                        }

                        public interface IWeight
                        {
                        double Weight { get; set; }
                        }

                        public interface IHeight
                        {
                        double Height { get; set; }
                        }

                        public class ClientA : Client, IWeight
                        {
                        public double Weight
                        {
                        get { return (double)GetValue(WeightProperty); }
                        set { SetValue(WeightProperty, value); }
                        }

                        public ClientA(string name, double weight)
                        : base(name)
                        {
                        Weight = weight;
                        }
                        }

                        public class ClientB : Client, IHeight
                        {
                        public double Height
                        {
                        get { return (double)GetValue(HeightProperty); }
                        set { SetValue(HeightProperty, value); }
                        }

                        public ClientB(string name, double height)
                        : base(name)
                        {
                        Height = height;
                        }
                        }

                        public class ClientC : Client, IHeight, IWeight
                        {
                        public double Height
                        {
                        get { return (double)GetValue(HeightProperty); }
                        set { SetValue(HeightProperty, value); }
                        }

                        public double Weight
                        {
                        get { return (double)GetValue(WeightProperty); }
                        set { SetValue(WeightProperty, value); }
                        }

                        public ClientC(string name, double weight, double height)
                        : base(name)
                        {
                        Weight = weight;
                        Height = height;
                        }

                        }

                        public static class ClientExt
                        {
                        public static double HeightInches(this IHeight client)
                        {
                        return client.Height * 39.3700787;
                        }

                        public static double WeightPounds(this IWeight client)
                        {
                        return client.Weight * 2.20462262;
                        }
                        }






                        share|improve this answer












                        share|improve this answer



                        share|improve this answer










                        answered May 24 '12 at 10:57









                        westonweston

                        39.3k1696168




                        39.3k1696168













                        • Why should we possibly use WPF classes here?

                          – Javid
                          Dec 15 '17 at 7:07



















                        • Why should we possibly use WPF classes here?

                          – Javid
                          Dec 15 '17 at 7:07

















                        Why should we possibly use WPF classes here?

                        – Javid
                        Dec 15 '17 at 7:07





                        Why should we possibly use WPF classes here?

                        – Javid
                        Dec 15 '17 at 7:07











                        2














                        Building on what Lucero suggested, I came up with this:



                        internal class Program
                        {
                        private static void Main(string args)
                        {
                        var a = new ClientA("Adam", 68);
                        var b = new ClientB("Bob", 1.75);
                        var c = new ClientC("Cheryl", 54.4, 1.65);

                        Console.WriteLine("{0} is {1:0.0} lbs.", a.Name, a.WeightPounds());
                        Console.WriteLine("{0} is {1:0.0} inches tall.", b.Name, b.HeightInches());
                        Console.WriteLine("{0} is {1:0.0} lbs and {2:0.0} inches.", c.Name, c.WeightPounds(), c.HeightInches());
                        Console.ReadLine();
                        }
                        }

                        public class Client
                        {
                        public string Name { get; set; }

                        public Client(string name)
                        {
                        Name = name;
                        }
                        }

                        public interface IWeight
                        {
                        double Weight { get; set; }
                        }

                        public interface IHeight
                        {
                        double Height { get; set; }
                        }

                        public class ClientA : Client, IWeight
                        {
                        public double Weight { get; set; }
                        public ClientA(string name, double weight) : base(name)
                        {
                        Weight = weight;
                        }
                        }

                        public class ClientB : Client, IHeight
                        {
                        public double Height { get; set; }
                        public ClientB(string name, double height) : base(name)
                        {
                        Height = height;
                        }
                        }

                        public class ClientC : Client, IWeight, IHeight
                        {
                        public double Weight { get; set; }
                        public double Height { get; set; }
                        public ClientC(string name, double weight, double height) : base(name)
                        {
                        Weight = weight;
                        Height = height;
                        }
                        }

                        public static class ClientExt
                        {
                        public static double HeightInches(this IHeight client)
                        {
                        return client.Height * 39.3700787;
                        }

                        public static double WeightPounds(this IWeight client)
                        {
                        return client.Weight * 2.20462262;
                        }
                        }


                        Output:



                        Adam is 149.9 lbs.
                        Bob is 68.9 inches tall.
                        Cheryl is 119.9 lbs and 65.0 inches.


                        It isn't quite as nice as I'd like, but it's not too bad either.






                        share|improve this answer


























                        • IMHO it's nicer than an accepted method

                          – Andrzej Martyna
                          Oct 24 '17 at 13:13











                        • Still not as efficient as PHP doest it.

                          – Digital Human
                          Jan 11 '18 at 7:15
















                        2














                        Building on what Lucero suggested, I came up with this:



                        internal class Program
                        {
                        private static void Main(string args)
                        {
                        var a = new ClientA("Adam", 68);
                        var b = new ClientB("Bob", 1.75);
                        var c = new ClientC("Cheryl", 54.4, 1.65);

                        Console.WriteLine("{0} is {1:0.0} lbs.", a.Name, a.WeightPounds());
                        Console.WriteLine("{0} is {1:0.0} inches tall.", b.Name, b.HeightInches());
                        Console.WriteLine("{0} is {1:0.0} lbs and {2:0.0} inches.", c.Name, c.WeightPounds(), c.HeightInches());
                        Console.ReadLine();
                        }
                        }

                        public class Client
                        {
                        public string Name { get; set; }

                        public Client(string name)
                        {
                        Name = name;
                        }
                        }

                        public interface IWeight
                        {
                        double Weight { get; set; }
                        }

                        public interface IHeight
                        {
                        double Height { get; set; }
                        }

                        public class ClientA : Client, IWeight
                        {
                        public double Weight { get; set; }
                        public ClientA(string name, double weight) : base(name)
                        {
                        Weight = weight;
                        }
                        }

                        public class ClientB : Client, IHeight
                        {
                        public double Height { get; set; }
                        public ClientB(string name, double height) : base(name)
                        {
                        Height = height;
                        }
                        }

                        public class ClientC : Client, IWeight, IHeight
                        {
                        public double Weight { get; set; }
                        public double Height { get; set; }
                        public ClientC(string name, double weight, double height) : base(name)
                        {
                        Weight = weight;
                        Height = height;
                        }
                        }

                        public static class ClientExt
                        {
                        public static double HeightInches(this IHeight client)
                        {
                        return client.Height * 39.3700787;
                        }

                        public static double WeightPounds(this IWeight client)
                        {
                        return client.Weight * 2.20462262;
                        }
                        }


                        Output:



                        Adam is 149.9 lbs.
                        Bob is 68.9 inches tall.
                        Cheryl is 119.9 lbs and 65.0 inches.


                        It isn't quite as nice as I'd like, but it's not too bad either.






                        share|improve this answer


























                        • IMHO it's nicer than an accepted method

                          – Andrzej Martyna
                          Oct 24 '17 at 13:13











                        • Still not as efficient as PHP doest it.

                          – Digital Human
                          Jan 11 '18 at 7:15














                        2












                        2








                        2







                        Building on what Lucero suggested, I came up with this:



                        internal class Program
                        {
                        private static void Main(string args)
                        {
                        var a = new ClientA("Adam", 68);
                        var b = new ClientB("Bob", 1.75);
                        var c = new ClientC("Cheryl", 54.4, 1.65);

                        Console.WriteLine("{0} is {1:0.0} lbs.", a.Name, a.WeightPounds());
                        Console.WriteLine("{0} is {1:0.0} inches tall.", b.Name, b.HeightInches());
                        Console.WriteLine("{0} is {1:0.0} lbs and {2:0.0} inches.", c.Name, c.WeightPounds(), c.HeightInches());
                        Console.ReadLine();
                        }
                        }

                        public class Client
                        {
                        public string Name { get; set; }

                        public Client(string name)
                        {
                        Name = name;
                        }
                        }

                        public interface IWeight
                        {
                        double Weight { get; set; }
                        }

                        public interface IHeight
                        {
                        double Height { get; set; }
                        }

                        public class ClientA : Client, IWeight
                        {
                        public double Weight { get; set; }
                        public ClientA(string name, double weight) : base(name)
                        {
                        Weight = weight;
                        }
                        }

                        public class ClientB : Client, IHeight
                        {
                        public double Height { get; set; }
                        public ClientB(string name, double height) : base(name)
                        {
                        Height = height;
                        }
                        }

                        public class ClientC : Client, IWeight, IHeight
                        {
                        public double Weight { get; set; }
                        public double Height { get; set; }
                        public ClientC(string name, double weight, double height) : base(name)
                        {
                        Weight = weight;
                        Height = height;
                        }
                        }

                        public static class ClientExt
                        {
                        public static double HeightInches(this IHeight client)
                        {
                        return client.Height * 39.3700787;
                        }

                        public static double WeightPounds(this IWeight client)
                        {
                        return client.Weight * 2.20462262;
                        }
                        }


                        Output:



                        Adam is 149.9 lbs.
                        Bob is 68.9 inches tall.
                        Cheryl is 119.9 lbs and 65.0 inches.


                        It isn't quite as nice as I'd like, but it's not too bad either.






                        share|improve this answer















                        Building on what Lucero suggested, I came up with this:



                        internal class Program
                        {
                        private static void Main(string args)
                        {
                        var a = new ClientA("Adam", 68);
                        var b = new ClientB("Bob", 1.75);
                        var c = new ClientC("Cheryl", 54.4, 1.65);

                        Console.WriteLine("{0} is {1:0.0} lbs.", a.Name, a.WeightPounds());
                        Console.WriteLine("{0} is {1:0.0} inches tall.", b.Name, b.HeightInches());
                        Console.WriteLine("{0} is {1:0.0} lbs and {2:0.0} inches.", c.Name, c.WeightPounds(), c.HeightInches());
                        Console.ReadLine();
                        }
                        }

                        public class Client
                        {
                        public string Name { get; set; }

                        public Client(string name)
                        {
                        Name = name;
                        }
                        }

                        public interface IWeight
                        {
                        double Weight { get; set; }
                        }

                        public interface IHeight
                        {
                        double Height { get; set; }
                        }

                        public class ClientA : Client, IWeight
                        {
                        public double Weight { get; set; }
                        public ClientA(string name, double weight) : base(name)
                        {
                        Weight = weight;
                        }
                        }

                        public class ClientB : Client, IHeight
                        {
                        public double Height { get; set; }
                        public ClientB(string name, double height) : base(name)
                        {
                        Height = height;
                        }
                        }

                        public class ClientC : Client, IWeight, IHeight
                        {
                        public double Weight { get; set; }
                        public double Height { get; set; }
                        public ClientC(string name, double weight, double height) : base(name)
                        {
                        Weight = weight;
                        Height = height;
                        }
                        }

                        public static class ClientExt
                        {
                        public static double HeightInches(this IHeight client)
                        {
                        return client.Height * 39.3700787;
                        }

                        public static double WeightPounds(this IWeight client)
                        {
                        return client.Weight * 2.20462262;
                        }
                        }


                        Output:



                        Adam is 149.9 lbs.
                        Bob is 68.9 inches tall.
                        Cheryl is 119.9 lbs and 65.0 inches.


                        It isn't quite as nice as I'd like, but it's not too bad either.







                        share|improve this answer














                        share|improve this answer



                        share|improve this answer








                        edited May 23 '17 at 11:33









                        Community

                        11




                        11










                        answered Mar 30 '15 at 20:05









                        mpenmpen

                        124k172648950




                        124k172648950













                        • IMHO it's nicer than an accepted method

                          – Andrzej Martyna
                          Oct 24 '17 at 13:13











                        • Still not as efficient as PHP doest it.

                          – Digital Human
                          Jan 11 '18 at 7:15



















                        • IMHO it's nicer than an accepted method

                          – Andrzej Martyna
                          Oct 24 '17 at 13:13











                        • Still not as efficient as PHP doest it.

                          – Digital Human
                          Jan 11 '18 at 7:15

















                        IMHO it's nicer than an accepted method

                        – Andrzej Martyna
                        Oct 24 '17 at 13:13





                        IMHO it's nicer than an accepted method

                        – Andrzej Martyna
                        Oct 24 '17 at 13:13













                        Still not as efficient as PHP doest it.

                        – Digital Human
                        Jan 11 '18 at 7:15





                        Still not as efficient as PHP doest it.

                        – Digital Human
                        Jan 11 '18 at 7:15











                        2














                        Traits can be implemented in C# 8 by using default interface methods. Java 8 introduced default interface methods for this reason too.



                        Using C# 8, you can write almost exactly what you proposed in the question. The traits are implemented by the IClientWeight, IClientHeight interfaces that provide a default implementation for their methods. In this case, they just return 0:



                        public interface IClientWeight
                        {
                        int getWeight()=>0;
                        }

                        public interface IClientHeight
                        {
                        int getHeight()=>0;
                        }

                        public class Client
                        {
                        public String Name {get;set;}
                        }


                        ClientA and ClientB have the traits but don't implement them. ClientC implements only IClientHeight and returns a different number, in this case 16 :



                        class ClientA : Client, IClientWeight{}
                        class ClientB : Client, IClientHeight{}
                        class ClientC : Client, IClientWeight, IClientHeight
                        {
                        public int getHeight()=>16;
                        }


                        When getHeight() is called in ClientB through the interface, the default implementation is called. getHeight() can only be called through the interface.



                        ClientC implements the IClientHeight interface so its own method is called. The method is available through the class itself.



                        public class C {
                        public void M() {
                        //Accessed through the interface
                        IClientHeight clientB=new ClientB();
                        clientB.getHeight();

                        //Accessed directly or through the interface
                        var clientC=new ClientC();
                        clientC.getHeight();
                        }
                        }


                        This SharpLab.io example shows the code produced from this example



                        Many of the traits features described in the PHP overview on traits can be implemented easily with default interface methods. Traits (interfaces) can be combined. It's also possible to define abstract methods to force classes to implement certain requirements.



                        Let's say we want our traits to have sayHeight() and sayWeight() methods that return a string with the height or weight. They'd need some way to force exhibiting classes (term stolen from the PHP guide) to implement a method that returns the height and weight :



                        public interface IClientWeight
                        {
                        abstract int getWeight();
                        String sayWeight()=>getWeight().ToString();
                        }

                        public interface IClientHeight
                        {
                        abstract int getHeight();
                        String sayHeight()=>getHeight().ToString();
                        }

                        //Combines both traits
                        public interface IClientBoth:IClientHeight,IClientWeight{}


                        The clients now have to implement thet getHeight() or getWeight() method but don't need to know anything about the say methods.



                        This offers a cleaner way to decorate



                        SharpLab.io link for this sample.






                        share|improve this answer






























                          2














                          Traits can be implemented in C# 8 by using default interface methods. Java 8 introduced default interface methods for this reason too.



                          Using C# 8, you can write almost exactly what you proposed in the question. The traits are implemented by the IClientWeight, IClientHeight interfaces that provide a default implementation for their methods. In this case, they just return 0:



                          public interface IClientWeight
                          {
                          int getWeight()=>0;
                          }

                          public interface IClientHeight
                          {
                          int getHeight()=>0;
                          }

                          public class Client
                          {
                          public String Name {get;set;}
                          }


                          ClientA and ClientB have the traits but don't implement them. ClientC implements only IClientHeight and returns a different number, in this case 16 :



                          class ClientA : Client, IClientWeight{}
                          class ClientB : Client, IClientHeight{}
                          class ClientC : Client, IClientWeight, IClientHeight
                          {
                          public int getHeight()=>16;
                          }


                          When getHeight() is called in ClientB through the interface, the default implementation is called. getHeight() can only be called through the interface.



                          ClientC implements the IClientHeight interface so its own method is called. The method is available through the class itself.



                          public class C {
                          public void M() {
                          //Accessed through the interface
                          IClientHeight clientB=new ClientB();
                          clientB.getHeight();

                          //Accessed directly or through the interface
                          var clientC=new ClientC();
                          clientC.getHeight();
                          }
                          }


                          This SharpLab.io example shows the code produced from this example



                          Many of the traits features described in the PHP overview on traits can be implemented easily with default interface methods. Traits (interfaces) can be combined. It's also possible to define abstract methods to force classes to implement certain requirements.



                          Let's say we want our traits to have sayHeight() and sayWeight() methods that return a string with the height or weight. They'd need some way to force exhibiting classes (term stolen from the PHP guide) to implement a method that returns the height and weight :



                          public interface IClientWeight
                          {
                          abstract int getWeight();
                          String sayWeight()=>getWeight().ToString();
                          }

                          public interface IClientHeight
                          {
                          abstract int getHeight();
                          String sayHeight()=>getHeight().ToString();
                          }

                          //Combines both traits
                          public interface IClientBoth:IClientHeight,IClientWeight{}


                          The clients now have to implement thet getHeight() or getWeight() method but don't need to know anything about the say methods.



                          This offers a cleaner way to decorate



                          SharpLab.io link for this sample.






                          share|improve this answer




























                            2












                            2








                            2







                            Traits can be implemented in C# 8 by using default interface methods. Java 8 introduced default interface methods for this reason too.



                            Using C# 8, you can write almost exactly what you proposed in the question. The traits are implemented by the IClientWeight, IClientHeight interfaces that provide a default implementation for their methods. In this case, they just return 0:



                            public interface IClientWeight
                            {
                            int getWeight()=>0;
                            }

                            public interface IClientHeight
                            {
                            int getHeight()=>0;
                            }

                            public class Client
                            {
                            public String Name {get;set;}
                            }


                            ClientA and ClientB have the traits but don't implement them. ClientC implements only IClientHeight and returns a different number, in this case 16 :



                            class ClientA : Client, IClientWeight{}
                            class ClientB : Client, IClientHeight{}
                            class ClientC : Client, IClientWeight, IClientHeight
                            {
                            public int getHeight()=>16;
                            }


                            When getHeight() is called in ClientB through the interface, the default implementation is called. getHeight() can only be called through the interface.



                            ClientC implements the IClientHeight interface so its own method is called. The method is available through the class itself.



                            public class C {
                            public void M() {
                            //Accessed through the interface
                            IClientHeight clientB=new ClientB();
                            clientB.getHeight();

                            //Accessed directly or through the interface
                            var clientC=new ClientC();
                            clientC.getHeight();
                            }
                            }


                            This SharpLab.io example shows the code produced from this example



                            Many of the traits features described in the PHP overview on traits can be implemented easily with default interface methods. Traits (interfaces) can be combined. It's also possible to define abstract methods to force classes to implement certain requirements.



                            Let's say we want our traits to have sayHeight() and sayWeight() methods that return a string with the height or weight. They'd need some way to force exhibiting classes (term stolen from the PHP guide) to implement a method that returns the height and weight :



                            public interface IClientWeight
                            {
                            abstract int getWeight();
                            String sayWeight()=>getWeight().ToString();
                            }

                            public interface IClientHeight
                            {
                            abstract int getHeight();
                            String sayHeight()=>getHeight().ToString();
                            }

                            //Combines both traits
                            public interface IClientBoth:IClientHeight,IClientWeight{}


                            The clients now have to implement thet getHeight() or getWeight() method but don't need to know anything about the say methods.



                            This offers a cleaner way to decorate



                            SharpLab.io link for this sample.






                            share|improve this answer















                            Traits can be implemented in C# 8 by using default interface methods. Java 8 introduced default interface methods for this reason too.



                            Using C# 8, you can write almost exactly what you proposed in the question. The traits are implemented by the IClientWeight, IClientHeight interfaces that provide a default implementation for their methods. In this case, they just return 0:



                            public interface IClientWeight
                            {
                            int getWeight()=>0;
                            }

                            public interface IClientHeight
                            {
                            int getHeight()=>0;
                            }

                            public class Client
                            {
                            public String Name {get;set;}
                            }


                            ClientA and ClientB have the traits but don't implement them. ClientC implements only IClientHeight and returns a different number, in this case 16 :



                            class ClientA : Client, IClientWeight{}
                            class ClientB : Client, IClientHeight{}
                            class ClientC : Client, IClientWeight, IClientHeight
                            {
                            public int getHeight()=>16;
                            }


                            When getHeight() is called in ClientB through the interface, the default implementation is called. getHeight() can only be called through the interface.



                            ClientC implements the IClientHeight interface so its own method is called. The method is available through the class itself.



                            public class C {
                            public void M() {
                            //Accessed through the interface
                            IClientHeight clientB=new ClientB();
                            clientB.getHeight();

                            //Accessed directly or through the interface
                            var clientC=new ClientC();
                            clientC.getHeight();
                            }
                            }


                            This SharpLab.io example shows the code produced from this example



                            Many of the traits features described in the PHP overview on traits can be implemented easily with default interface methods. Traits (interfaces) can be combined. It's also possible to define abstract methods to force classes to implement certain requirements.



                            Let's say we want our traits to have sayHeight() and sayWeight() methods that return a string with the height or weight. They'd need some way to force exhibiting classes (term stolen from the PHP guide) to implement a method that returns the height and weight :



                            public interface IClientWeight
                            {
                            abstract int getWeight();
                            String sayWeight()=>getWeight().ToString();
                            }

                            public interface IClientHeight
                            {
                            abstract int getHeight();
                            String sayHeight()=>getHeight().ToString();
                            }

                            //Combines both traits
                            public interface IClientBoth:IClientHeight,IClientWeight{}


                            The clients now have to implement thet getHeight() or getWeight() method but don't need to know anything about the say methods.



                            This offers a cleaner way to decorate



                            SharpLab.io link for this sample.







                            share|improve this answer














                            share|improve this answer



                            share|improve this answer








                            edited Nov 23 '18 at 17:27

























                            answered Nov 23 '18 at 16:44









                            Panagiotis KanavosPanagiotis Kanavos

                            55.3k483110




                            55.3k483110























                                0














                                This sounds like PHP's version of Aspect Oriented Programming. There are tools to help like PostSharp or MS Unity in some cases. If you want to roll-your-own, code-injection using C# Attributes is one approach, or as suggested extension methods for limited cases.



                                Really depends how complicated you want to get. If you are trying to build something complex I'd be looking at some of these tools to help.






                                share|improve this answer
























                                • Does AoP/PostSharp/Unity allow adding new members that become part of the static type system? (My limited AoP experience was just with annotation cut-points and similar..)

                                  – user166390
                                  May 24 '12 at 0:03













                                • PostSharp rewrites the IL code and should be able to do that, yes.

                                  – Lucero
                                  May 24 '12 at 0:15











                                • Yes I believe so, via aspects for member/interface introduction (at the IL level as noted). My experience is limited also, but I've not had much practical opportunity to get too deep into this approach.

                                  – RJ Lohan
                                  May 24 '12 at 0:38
















                                0














                                This sounds like PHP's version of Aspect Oriented Programming. There are tools to help like PostSharp or MS Unity in some cases. If you want to roll-your-own, code-injection using C# Attributes is one approach, or as suggested extension methods for limited cases.



                                Really depends how complicated you want to get. If you are trying to build something complex I'd be looking at some of these tools to help.






                                share|improve this answer
























                                • Does AoP/PostSharp/Unity allow adding new members that become part of the static type system? (My limited AoP experience was just with annotation cut-points and similar..)

                                  – user166390
                                  May 24 '12 at 0:03













                                • PostSharp rewrites the IL code and should be able to do that, yes.

                                  – Lucero
                                  May 24 '12 at 0:15











                                • Yes I believe so, via aspects for member/interface introduction (at the IL level as noted). My experience is limited also, but I've not had much practical opportunity to get too deep into this approach.

                                  – RJ Lohan
                                  May 24 '12 at 0:38














                                0












                                0








                                0







                                This sounds like PHP's version of Aspect Oriented Programming. There are tools to help like PostSharp or MS Unity in some cases. If you want to roll-your-own, code-injection using C# Attributes is one approach, or as suggested extension methods for limited cases.



                                Really depends how complicated you want to get. If you are trying to build something complex I'd be looking at some of these tools to help.






                                share|improve this answer













                                This sounds like PHP's version of Aspect Oriented Programming. There are tools to help like PostSharp or MS Unity in some cases. If you want to roll-your-own, code-injection using C# Attributes is one approach, or as suggested extension methods for limited cases.



                                Really depends how complicated you want to get. If you are trying to build something complex I'd be looking at some of these tools to help.







                                share|improve this answer












                                share|improve this answer



                                share|improve this answer










                                answered May 23 '12 at 23:59









                                RJ LohanRJ Lohan

                                5,41732450




                                5,41732450













                                • Does AoP/PostSharp/Unity allow adding new members that become part of the static type system? (My limited AoP experience was just with annotation cut-points and similar..)

                                  – user166390
                                  May 24 '12 at 0:03













                                • PostSharp rewrites the IL code and should be able to do that, yes.

                                  – Lucero
                                  May 24 '12 at 0:15











                                • Yes I believe so, via aspects for member/interface introduction (at the IL level as noted). My experience is limited also, but I've not had much practical opportunity to get too deep into this approach.

                                  – RJ Lohan
                                  May 24 '12 at 0:38



















                                • Does AoP/PostSharp/Unity allow adding new members that become part of the static type system? (My limited AoP experience was just with annotation cut-points and similar..)

                                  – user166390
                                  May 24 '12 at 0:03













                                • PostSharp rewrites the IL code and should be able to do that, yes.

                                  – Lucero
                                  May 24 '12 at 0:15











                                • Yes I believe so, via aspects for member/interface introduction (at the IL level as noted). My experience is limited also, but I've not had much practical opportunity to get too deep into this approach.

                                  – RJ Lohan
                                  May 24 '12 at 0:38

















                                Does AoP/PostSharp/Unity allow adding new members that become part of the static type system? (My limited AoP experience was just with annotation cut-points and similar..)

                                – user166390
                                May 24 '12 at 0:03







                                Does AoP/PostSharp/Unity allow adding new members that become part of the static type system? (My limited AoP experience was just with annotation cut-points and similar..)

                                – user166390
                                May 24 '12 at 0:03















                                PostSharp rewrites the IL code and should be able to do that, yes.

                                – Lucero
                                May 24 '12 at 0:15





                                PostSharp rewrites the IL code and should be able to do that, yes.

                                – Lucero
                                May 24 '12 at 0:15













                                Yes I believe so, via aspects for member/interface introduction (at the IL level as noted). My experience is limited also, but I've not had much practical opportunity to get too deep into this approach.

                                – RJ Lohan
                                May 24 '12 at 0:38





                                Yes I believe so, via aspects for member/interface introduction (at the IL level as noted). My experience is limited also, but I've not had much practical opportunity to get too deep into this approach.

                                – RJ Lohan
                                May 24 '12 at 0:38


















                                draft saved

                                draft discarded




















































                                Thanks for contributing an answer to Stack Overflow!


                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid



                                • Asking for help, clarification, or responding to other answers.

                                • Making statements based on opinion; back them up with references or personal experience.


                                To learn more, see our tips on writing great answers.




                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function () {
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f10729230%2fhow-would-you-implement-a-trait-design-pattern-in-c%23new-answer', 'question_page');
                                }
                                );

                                Post as a guest















                                Required, but never shown





















































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown

































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown







                                Popular posts from this blog

                                Costa Masnaga

                                Fotorealismo

                                Sidney Franklin