2

I would like to completely replace a method of a class that I did not write. I'm having difficulty finding an answer to this because I'm not sure what it's called, because I don't think it's technically considered overriding.

For example:

Say I have some code that uses the List object extensively in a lot of locations. Pretty often I'm calling the Sort method on these objects, but now I would like to change the implementation of the Sort method to preform some additional actions.

I could create a new class, MyList, that inherits from List and overrides the Sort method, but that would mean I have to go through all of my code and make sure I change all the List objects to MyList. This could create some issues since I am using List all over the place and could easily miss a few objects

This isn't the literal case, but hopefully the example makes sense. I know what I'm trying to do may be considered bad design, but I'd still like to know if this is possible.

Daniel Daranas
  • 22,454
  • 9
  • 63
  • 116
Weebs
  • 435
  • 6
  • 17
  • it's called a shadow method, but I'm pretty sure it won't help you here: http://stackoverflow.com/questions/673779/what-is-shadowing – BlackICE Aug 01 '13 at 18:20
  • You could create an extension method, but you cannot override an existing method so you would still need to change the call everywhere that it is used. – Kevin DiTraglia Aug 01 '13 at 18:21
  • Can you implement sorting inside the objects in the list instead? And let them help you get the right sort order without replacing `List` ? – Lasse V. Karlsen Aug 01 '13 at 18:21
  • 1
    You may find the following useful in this context: http://stackoverflow.com/questions/3021797/how-moles-isolation-framework-is-implemented – Martin Aug 01 '13 at 18:21
  • Without subclassing, you could write an extension method to effectively add a `SortAnd___` method to the `List` class. But a method that is just called `Sort` should sort and do nothing else. – JosephHirn Aug 01 '13 at 18:23
  • Removed irrelevant asp.net and mvc tags – John Saunders Aug 01 '13 at 18:26

3 Answers3

2

This is the reason for coding to interfaces instead of implementations, and using IoC/DI to retrieve your implementations.

For example, if your code was originally:

interface IFoo { void Go(); }
class Foo : IFoo { public void Go() { } }
class SomeOtherFoo : IFoo { public void Go() { } }

IFoo foo = MyIoCLibrary.Get<IFoo>(); // instead of new Foo()
foo.Go();

or

public class SomeClass : IWhatever {

    private IFoo _foo;

    // Your DI library will call this constructor automatically
    public SomeClass(IFoo foo) {
        _foo = foo;
    }
}

Let's say your IoC library pointed IFoo to Foo. At runtime all of your IFoo instances will be Foo, so they'd do whatever Foo does. Somewhere down the road, you want to use SomeOtherFoo instead - you'd just change your configuration to point IFoo to SomeOtherFoo and never have to touch another line of code.

But if you've already got implementations everywhere, you wouldn't be able to use this technique - you'd first have to replace all of your Foo variables with IFoo, and replace the instantiations with the applicable IoC/DI methods.

Joe Enos
  • 39,478
  • 11
  • 80
  • 136
  • If you are using this approach, it will be easy to use the Decorator pattern in order to augment your object without messing with its source. – mao47 Aug 01 '13 at 18:40
0

If you want to add functionality to an existing class without inheriting from it, extension methods are generally the best way to go.

In this particular case, however, that's not necessary. If you want to change the way the Sort method sorts the list, the best way is to create an IComparer<T> or more simply a Comparison<T>, and then call the appropriate override.

For example, suppose you had a List<int> and you wanted to sort it such that all even numbers came first. You can just do this:

var list = new List<int> { 1, 2, 3, 4, 5 };
list.Sort((x, y) => (x % 2 == y % 2) ? x - y : x % 2 - y % 2);
// list = { 2, 4, 1, 3, 5 }
p.s.w.g
  • 146,324
  • 30
  • 291
  • 331
  • 3
    If he is really interested in Sort then this is a great solution. but seems like he just gave that as an example??? – phillip Aug 01 '13 at 18:27
0

I think you want Composition not Inheritance.

I do this most often when I want everything an object has but no access to it's internals and maybe add some additional functionality. So you will wrap every method from the object you want and then implement your own functionality within the specific method(s).

Great example here. implementation of composition and aggregation in C#?

Community
  • 1
  • 1
phillip
  • 2,618
  • 19
  • 22