【问题标题】:How to cause method calls enter a different method first如何导致方法调用先进入不同的方法
【发布时间】:2021-03-15 16:37:24
【问题描述】:

我什至不知道如何正确命名我的问题,所以如果有任何建议,我都会更改它。我遇到的问题是这个;我有一个对象有一些处置工作要做。使用“using”关键字和范围是不可能的,因为对象可以使用很长时间。我不想依赖程序员记住对这些对象调用 Dispose(),因为他可能会忘记。相反,我希望对象的所有或部分方法像这样工作:

  1. 所有方法都先进入某个通用函数
  2. 这个通用函数调用原始方法
  3. 根据通用方法的布尔参数(例如),通用方法可能通过一些清理工作(处置)完成

所以如果我有 10 种方法,我希望它们都进入同一个地方,完成它们的工作,然后处理掉。而且我不想在这 10 种方法中重复调用 dispose 方法。

例子:

public void SomeBaseFunc(bool shouldDispose) //all methods first get drained here
{
//call whatever original func that the client called
//query bool param and dispose
}

【问题讨论】:

  • “我不想在 10 个方法中的每一个中重复调用 dispose 方法” - 为什么不呢?这比将所有呼叫站点更改为 yourClass.Foo(yc => yc.OriginalMethod()) 工作量少。
  • 嗨。我不是 C# 专家,但我认为面向方面的编程可以帮助你
  • I do not want to rely on the programmer to remember call Dispose() on these objects because he might forget 然后解雇他。或者像其他人一样依赖终结器
  • 该类应该实现IDisposable,并且消费者的工作要记住正确处理它,using 或其他方式。这是 C# 程序员生活中的一部分。如果他们忘记了,那是他们,而不是你。
  • 您能详细说明一下这个场景吗?在我从事 C# 编程二十年的情况下,我很难想象潜在的问题是什么......除非有问题的对象正在处理一些非托管代码,在这种情况下,您可能应该实现一个终结器。

标签: c# .net oop design-patterns reflection


【解决方案1】:

假设你的类中没有十个,而是三个方法,最简单的方法是修改它们的签名并让它们调用你的“dispose但不是真正的dispose”方法:

public class YourClass
{
    public void Foo(int i, bool shouldDispose)
    {
        // Do the Foo(i) business

        DoTheDisposeOrNot(shouldDispose);
    }

    public void Bar(string s, bool shouldDispose)
    {
        // Do the Bar(s) business

        DoTheDisposeOrNot(shouldDispose);
    }
    
    public void Baz(bool b, bool shouldDispose)
    {
        // Do the Baz(b) business

        DoTheDisposeOrNot(shouldDispose);
    }
}

这是三个修改(参数)和三个添加(方法调用),你就完成了。

在调用站点上,您将yourInstance.Foo(42) 修改为yourInstance.Foo(42, true)(或者您给shouldDispose 一个合理的默认值。您需要重新编译,或者添加一个重载)。

现在考虑一个替代方案,将这个责任转移给调用者。您可以创建这样的方法:

public void SomeBaseFunc(Action<YourClass> action, bool shouldDispose)
{
    action(this);
    DoTheDisposeOrNot(shouldDispose);
}

无论如何,您的呼叫者都必须修改他们的呼叫站点:

yourInstance.SomeBaseFunc(f => f.Foo(42), true);

要点是:

  • 无论如何都需要在调用站点上进行修改
  • 很丑
  • 调用者可以忘记或拒绝进行此修改,代码仍将调用yourInstance.Foo(42),省略您希望引入的dispose-call

所以,答案是Action&lt;T&gt;,但真正的答案是:添加那个参数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-19
    • 2020-08-15
    相关资源
    最近更新 更多