2

我想完全替换一个我没有写的类的方法。我很难找到答案,因为我不确定它叫什么,因为我不认为它在技术上被认为是压倒一切的。

例如:

假设我有一些代码在很多地方广泛使用 List 对象。我经常对这些对象调用 Sort 方法,但现在我想更改 Sort 方法的实现以执行一些额外的操作。

我可以创建一个新类 MyList,它继承自 List 并覆盖 Sort 方法,但这意味着我必须检查所有代码并确保将所有 List 对象更改为 MyList。这可能会产生一些问题,因为我到处都在使用 List 并且很容易错过一些对象

这不是字面上的情况,但希望这个例子是有意义的。我知道我正在尝试做的事情可能被认为是糟糕的设计,但我仍然想知道这是否可能。

4

3 回答 3

2

这就是编码接口而不是实现的原因,并使用 IoC/DI 来检索您的实现。

例如,如果您的代码最初是:

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;
    }
}

假设您的 IoC 库IFoo指向Foo. 在运行时,您的所有IFoo实例都将是Foo,所以他们会做任何事情Foo。在未来的某个地方,您想SomeOtherFoo改用 - 您只需将配置更改为指向IFooSomeOtherFoo而不必触及另一行代码。

但是,如果您已经到处都有实现,您将无法使用此技术 - 您首先必须将所有Foo变量IFoo替换为 ,然后将实例化替换为适用的 IoC/DI 方法。

于 2013-08-01T18:32:48.350 回答
0

如果您想在不继承现有类的情况下向现有类添加功能,扩展方法通常是最好的方法。

但是,在这种特殊情况下,这不是必需的。如果要更改Sort方法对列表进行排序的方式,最好的方法是创建一个IComparer<T>或更简单的 a Comparison<T>,然后调用适当的覆盖。

例如,假设您有 aList<int>并且您想对它进行排序,以使所有偶数都排在第一位。你可以这样做:

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 }
于 2013-08-01T18:25:27.233 回答
0

我认为您想要Composition 而不是 Inheritance

当我想要一个对象拥有的所有东西但无法访问它的内部并且可能添加一些额外的功能时,我最常这样做。因此,您将从您想要的对象中包装每个方法,然后在特定方法中实现您自己的功能。

很好的例子。 在 C# 中实现组合和聚合?

于 2013-08-01T18:33:44.560 回答