我想完全替换我没写过的类的方法。我很难找到答案,因为我不确定它叫什么,因为我不认为它在技术上被认为是压倒一切。
例如:
假设我有一些代码在很多地方广泛使用List对象。我经常在这些对象上调用Sort方法,但现在我想更改Sort方法的实现以执行一些额外的操作。
我可以创建一个新的类MyList,它继承自List并覆盖Sort方法,但这意味着我必须完成所有代码并确保将所有List对象更改为MyList。这可能会产生一些问题,因为我在整个地方使用List并且很容易错过一些对象
这不是字面意思,但希望这个例子有意义。我知道我想要做的事可能被认为是糟糕的设计,但我仍然想知道这是否可行。
答案 0 :(得分: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
- 您只需将配置更改为指向IFoo
至SomeOtherFoo
,而无需触及另一行代码。
但是如果你已经到处都有实现,那么你将无法使用这种技术 - 首先必须用Foo
替换所有IFoo
变量,并替换使用适用的IoC / DI方法进行实例化。
答案 1 :(得分:0)
如果要在不继承功能的情况下向现有类添加功能,extension methods通常是最好的方法。
然而,在这种特殊情况下,这不是必要的。如果您想更改Sort
方法对列表进行排序的方式,最好的方法是创建IComparer<T>
或更简单的Comparison<T>
,然后调用相应的覆盖。
例如,假设您有一个List<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 }
答案 2 :(得分:0)
我想你想要Composition not Inheritance。
当我想要一个对象所拥有但却无法访问它的内部并且可能添加一些额外的功能时,我经常这样做。因此,您将从所需的对象中包装每个方法,然后在特定方法中实现您自己的功能。
这里的好例子。 implementation of composition and aggregation in C#?