Skip to content

Instantly share code, notes, and snippets.

@hodzanassredin
Last active August 29, 2015 14:01
Show Gist options
  • Save hodzanassredin/d040b9fce4c5e8171b25 to your computer and use it in GitHub Desktop.
Save hodzanassredin/d040b9fce4c5e8171b25 to your computer and use it in GitHub Desktop.
composition over inheritance pattern which doesn't require to define forward methods
using System;
using Traits;
namespace Test
{
public class A<T> : Trait<T>
{
public string Prop {get;set;}
public A (T self, string prop) : base(self){Prop = prop;}
public virtual void Foo() { Console.WriteLine("A.Foo " + Prop); }
}
public class B<T> : Trait<T>
{
public B (T self) : base(self){}
public void Bar() { Console.WriteLine("B.Bar"); }
}
public class C<T> : Trait<T> where T : Has<A<T>> //require A trait and proxyibg it
{
public C (T self, string aProp) : base(self){ this.GetTrait<A<T>,T>().Prop = aProp;}
public void Add() {
Console.WriteLine ("add with a foo");
this.GetTrait<A<T>,T>().Foo ();
}
}
public class Test : Has<A<Test>>, Has<B<Test>>, Has<C<Test>>{
internal class AOverrides: A<Test>{
public AOverrides (Test self, string prop) : base(self, prop){}
public override void Foo() {
Console.WriteLine("Foo override");
base.Foo ();
Console.WriteLine("method custom forwarding");
this.GetTrait<B<Test>, Test> ().Bar ();
}
}
public Test ()
{
_a = new AOverrides (this, "a prop val");
_b = new B<Test> (this);
_c = new C<Test> (this, "c prop val");
}
private A<Test> _a;
A<Test> Has<A<Test>>.Trait {get {return _a;}}
private B<Test> _b;
B<Test> Has<B<Test>>.Trait {get {return _b;}}
private C<Test> _c;
C<Test> Has<C<Test>>.Trait {get {return _c;}}
public void DoTests(){
Console.WriteLine ("Test");
}
}
class MainClass
{
public static void Main (string[] args)
{
var a = new Test ().GetTrait<A<Test>,Test>();
a.Foo();
var b = a.GetTrait<B<Test>, Test>();
b.Bar();
var c = b.GetTrait<C<Test>, Test>();
c.Add();
c.Self.DoTests ();
Console.ReadKey ();
}
}
}
using System;
namespace Traits
{
public interface Has<T>{T Trait {get;}}
public static class HasExt{
public static TRAIT GetTrait<TRAIT, SELF>(this SELF self) where SELF : Has<TRAIT>{
return self.Trait;
}
public static TRAIT GetTrait<TRAIT, SELF>(this Trait<SELF> self) where SELF : Has<TRAIT>{
return self.Self.Trait;
}
}
public class Trait<T>{
public readonly T Self;
public Trait (T self){this.Self = self;}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment