views:

183

answers:

5

Hi!

I have 4 base classes:

class A { virtual SomeMethod () { <code> } }
class A<T> { virtual SomeMethod () { <code> } }

class B { virtual SomeMethod () { <code> } }
class B<T2> { virtual SomeMethod () { <code> } }

Now, i have 4 implementations (each implementation is derived from the corresponding base type).

class Aa : A { override SomeMethod () { <code> } }
class Aa<Tt> : A<T> { override SomeMethod () { <code> } }

class Bb : b { override SomeMethod () { <code> } }
class Bb<Tt2> : B<T2> { override SomeMethod () { <code> } }

Now, i need to add SomeMethod implementation (it should be an override for the one from the base class). The SAME ONE for all of the mentioned derived classes.

What is the best solution? (i will share all my ideas right after the question is solved. since if i put my implementation here, the discussion will most likely go my direction, but i'm not quite sure if i'm right).

Thank you for your great ideas!!

+4  A: 

So you want one implementation for some 4 classes, and a different implementation for some other 4 classes? Perhaps the Strategy pattern would work.

interface ISomeMethodStrategy {
    string SomeMethod(string a, string b);
}

class DefaultStrategy : ISomeMethodStrategy {
    public string SomeMethod(string a, string b) { return a + b; }
    public static ISomeMethodStrategy Instance = new DefaultStrategy();
}
class DifferentStrategy : ISomeMethodStrategy {
    public string SomeMethod(string a, string b) { return b + a; }
    public static ISomeMethodStrategy Instance = new DifferentStrategy();
}

class A {
    private ISomeMethodStrategy strategy;
    private string a, b, c;
    public A() : this(DefaultStrategy.Instance) {}
    protected A(ISomeMethodStrategy strategy){
        this.strategy = strategy;
    }
    public void SomeMethod() {
        a = strategy.SomeMethod(b, c);
    }
}

class Aa : A {
    public Aa() : base(DifferentStrategy.Instance) {}
}

I've implemented the pattern here with an interface, but you can do the same with delegates.

Matt Howells
i already have this method.It exists as virtual in all the base classes. in all derived classes it should be an override. let me change the question, just a min
ifesdjeen
nice one, thanks for this example
Mark Dickinson
+3  A: 

A). it would be better if you did post your implementation regardless of whther you think it would skew anything

B). the concept of having a class A and a generic form class A<T> seems really alien. It's like your generic class has an exclusion for one specific case, which means it's less generic than other generics, i.e. wierd.

C). Why would you not just have all 4 base classes inherit from a higher class X if you mean to literally have the same method on each, or from an interface if you merely mean for them to implement this common method. Seems too obvious, have I missed something in your question?

annakata
c is bacically impossible since i'm deriving all the classes from some base MVC class.b. it may seem alien for you, i'm not blaming you for that. but there are some reasons for that, really.a. actually, the implementation is in progress(( unfortunately
ifesdjeen
I disagree that having A and A<T> is alien. Its like IEnumerable and IEnumerable<T>.
Matt Howells
Well not really, IEnumerable is kind of a hangover predating the generic form.
annakata
A: 

I am assuming that you want to have a single method that is shared (and overridable) between all implementations. The non-generic classes assume a default type that, say int.

Therefore you could create a single originating base class.

public class Origin {
   public virtual void SomeSharedOverrideMethod(int data) { }
}

class A : Origin {

   public void MethodForAImpl() {
       base.SomeSharedOverrideMethod(23);
   }
}

class A<T> : Origin {

   public void MethodForGenericAImpl() {
       base.SomeSharedOverrideMethod(45);
   }
}

class B : Origin
class B<T> : Origin

Is this what you require?

Adrian Regan
exactly! but i need to SHARE this SomeSharedOverrideMethod beetween 4 classes
ifesdjeen
when you say share do you mean share the implementation or just the signature of the method?
Mark Dickinson
Does the shared method require parameters or work on the generic type? If not the all you need is a simple base class with the virtual method in it, derived classes can override as required, but otherwise the code is shared amongst derived implementations
Adrian Regan
share the implementation
ifesdjeen
no, no generic types. just let's say SomeMethod (int i)
ifesdjeen
It sounds as though you have conflict here, if you want to share the implementation, in my mind you either have to put it in a virtual method and have C as a base class, or accept extension methods as a necessary evil. I'm not sure why you must override if you want the base implementation, you can call the base implementation in your override if you need to.
Mark Dickinson
Then make origin non-generic and put int in the parameter for SomeSharedOverrideMethod(int value). All classes derive from Origin
Adrian Regan
I have modified the original post to remove generics in the Origin class and examples of derived classes 'sharing' the method.
Adrian Regan
+1  A: 

Hi!

What about interfaces and composition instead of inheritance?

for example you create a new interface

interface myinterface
{
   void doSomethingCool();
}

than a new class which implements it

class interfaceImpl: myinterface
{
    public void doSomethingCool()
    {
         ... some code
    }
}

than with

class A : myinterface
{
  private interfaceImpl interf = MyInterfaceFactory.Build(args);

  public void doSomethingCool()
  {
      interf.doSomethingCool();
  }
}

so you can have the same behaviour in class A, B and all derived classes and you can also override it.

hth

nWorx
rather then doing this, i would create a static method in some class and run the method from there...
ifesdjeen
yes you could do this with a static method, but you would lose flexibility... a more flexibel approach would be to get the interface implenentation instance with a factory pattern.. i will correct the answer...
nWorx
A: 

The question is really asking how to do mix-ins in C#.

You could use a sledgehammer and adopt something like LinFu ; there are other approaches that involve opening up the base definitions to add extra generic parameters (the mix-in object). They all involve working around a deliberate choice in the language design.

Steve Gilham