views:

393

answers:

2

I have the following Model pattern:

public abstract class PARENTCLASS {...}
public class CHILD_A_CLASS : PARENTCLASS{...}
public static class EXTENSION{
  public static METHOD(this PARENTCLASS parent){...}
  public static METHOD(this CHILD_A_CLASS child) {...}
}

Something like above, of course there will be more child (and grandchild) classes but I just put one of them. The problem is, when I called the extension method like the following:

PARENTCLASS cc = new CHILD_A_CLASS();
cc.METHOD();

It will execute the PARENT Extension Method instead of my-expected CHILD extension method. Anyone have idea on how to implement this? (I'm not considering putting the METHOD itself into the class and let it do inheritance because I want to keep the model class clean and away from other logic).

+4  A: 

It is certainly possible to overload extension methods. Your code is an example of exactly how to do so.

What you appear to want though is the ability to override extension methods in such a way that the runtime type of the object will determine the extension method call. Much like defining a virtual method on a class. There is no specific language syntax support for such a feature.

If this is really important to you though, it's possible to hand implement the feature. It requires a bit of brute force but it will get the job done. For example ...

public static class Extension {
  public static void Method(this ParentClass p) { 
    var c = p as ChildAClass;
    if ( c != null ) {
      Method(c);
    } else {
      // Do parentclass action
    }
  }
  public static void Method(this ChildAClass c) {
    ...
  }
}
JaredPar
Thanks. I think type casting would be too costly for execute and also quite clumsy to maintain the code like this. I think I would look for alternative method to implement this.
xandy
type casting is quite fast, though it may indeed be messy to maintain.
Alex Martelli
Your proposal is not polymorphic, the selected method is only correct fir the compile reference type and not the runtime type. Too put it briefly it's not true overriding - I believe is a bad practice because it won't work all the time and just lead to inconsistencies and look wrong and cause more problems. I think extension methods are wrong as they hide the fact that these methods are not dynamically dispatched.
mP
In short like many (most ?) syntacticsl sugar inspired constructs they are just wrong and inspired by laziness rather actually adding something behaviourly new.
mP
@mP - Yes, the above code has its problems, simply because it is silly to reimplement virtual method dispatch by hand when the language feature already exists to do it for you. But you probably need to read up on what the "is" operator does. It checks the runtime type. So the implementation above does select the correct method at runtime. Also, extension methods being statically dispatched does not make them wrong. Only virtual methods are dynamically selected. Are non-virtual ordinary methods "wrong"?
Daniel Earwicker
@mP, it is polymorphic in the sense that it will *eventually* call the method based on the runtime type. The "is" operator is a cast operation. As I said, this is a brute force method and I do advise against it. However it will *work* to a degree if you are careful.
JaredPar
+1  A: 

Unfortunately I don't think you will be able to get what you want here. Extension methods are static, and static methods cannot be virtual.

You could work around this with something like JaredPar's solution.

If your goal is to separate your model from some implementation, I suggest you look into the Bridge Pattern (GOF). "Separate an abstraction from an implementation" This may help to separate your concerns and keep your model class cleaner.

Matt Brunell