【问题标题】:Replace a class method without inheritance替换没有继承的类方法
【发布时间】:2023-03-17 05:41:01
【问题描述】:

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

例如:

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

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

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

【问题讨论】:

  • 它被称为影子方法,但我很确定它在这里对你没有帮助:stackoverflow.com/questions/673779/what-is-shadowing
  • 您可以创建一个扩展方法,但您不能覆盖现有方法,因此您仍然需要在使用它的任何地方更改调用。
  • 你可以在列表中的对象内部实现排序吗?并让他们帮助您获得正确的排序顺序,而无需替换 List<T>
  • 在这种情况下,您可能会发现以下内容很有用:stackoverflow.com/questions/3021797/…
  • 如果不进行子类化,您可以编写扩展方法来有效地将SortAnd___ 方法添加到List 类。但是一个名为Sort 的方法应该排序并且什么都不做。

标签: c# polymorphism shadow


【解决方案1】:

这就是编码接口而不是实现的原因,并使用 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 方法。

【讨论】:

  • 如果您使用这种方法,则可以轻松使用装饰器模式来扩充您的对象,而不会弄乱其来源。
【解决方案2】:

我想你想要Composition not Inheritance

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

这里有很好的例子。 implementation of composition and aggregation in C#?

【讨论】:

    【解决方案3】:

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

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

    例如,假设您有一个List&lt;int&gt;,并且您想对它进行排序,以使所有偶数都排在第一位。你可以这样做:

    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 }
    

    【讨论】:

    • 如果他真的对 Sort 感兴趣,那么这是一个很好的解决方案。但似乎他只是举了一个例子???
    猜你喜欢
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-12
    • 1970-01-01
    • 2013-07-01
    相关资源
    最近更新 更多