4

A()使用 C#,如果在 function之前调用function ,我需要做一些额外的工作C()。如果在两者之间调用了任何其他函数A()C()那么我不想做那些额外的工作。任何需要最少代码重复的想法?

我试图避免flag = false;在每个函数中添加类似的行B1......BN

这是一个非常基本的例子:

bool flag = false;

void A()
{
    flag = true;
}

void B1()
{
    ...
}

void B2()
{
    ...
}

void C()
{
    if (flag) 
    {
        //do something
    }
}

上面的例子只是使用了一个简单的案例,但我愿意使用布尔值以外的东西。重要的是我希望能够设置和重置各种标志,以便C()知道如何相应地表现。

感谢您的帮助。如果您需要澄清,我将编辑我的帖子。

4

4 回答 4

7

为什么不将您的“额外工作”纳入一个记忆函数(即缓存其结果的函数)?每当您需要这项工作时,您只需调用此函数,如果缓存是新的,它将短路。每当该工作变得陈旧时,就使缓存无效。在上面你相当奇怪的例子中,我认为你需要在每个 B 中调用一个函数,在 C 中调用一个函数。对 A 的调用将使缓存无效。

如果您正在寻找解决方法(即一些巧妙的方法来捕获所有函数调用并插入此调用),我真的不会打扰。我可以设想一些疯狂的运行时反射代理类生成,但你应该让你的代码流清晰明了;如果每个功能都依赖于已经完成的工作,只需在每个功能中调用“doWork”。

于 2010-04-12T23:07:07.660 回答
3

如果调用一种方法会改变另一种方法的行为,那么您的设计听起来过于紧密耦合,因此您必须确保以正确的顺序调用它们。这是一个重要的危险信号。

听起来像一些重构是为了。在没有看到更多真实代码的情况下给出建议有点棘手,但这是正确方向的一点。

考虑向 C 中添加一个参数,如下所示:

void C(bool DoExtraWork) {
  if (DoExtraWork)...
}

当然,“DoExtraWork”应该在调用者的上下文中命名为有意义的东西。

于 2010-04-12T23:13:49.127 回答
1

我通过一个简单的状态机解决了一个类似情况的问题(即需要知道是否在 C 之前直接调用了 A)。本质上,我使用枚举和属性构建了一个状态对象来管理/查询状态。

当调用我的 A() 等效项时,它将使业务逻辑块存储在指示调用 A 的状态之外。如果调用了其他方法(你的 B 的),它会将状态切换到其他几个状态之一(我的情况有点复杂),然后当 C() 被调用时,查询业务逻辑片段以确定我们是否将调用一些方法 D(),该方法具有“仅当 A 被调用时”功能。

我怀疑有多种方法可以解决这个问题,但我喜欢我采用的状态机方法,因为它允许我扩展最初的二进制情况以处理更复杂的多状态情况。

我很幸运,多线程在我的情况下不是问题,因为这往往会使事情变得更有趣,但状态机也可能在这种情况下工作。

只是我的两分钱。

于 2010-04-12T23:28:51.800 回答
0

我不建议这样做,但到底是什么:如果您愿意替换所有简单的方法调用:

A();

...使用如下语法:

// _lastAction is a class-level Action member
(_lastAction = new Action(A)).Invoke();

...然后在C()你里面可以做这样的检查:

void C()
{
    if (_lastAction.Method.Name == "A")
    {

    }
}

这可能不是线程安全的(并且它不会在没有一点修补的情况下通过混淆器运行的代码运行),所以我不会在没有大量测试的情况下使用这样的东西。我也不会使用像这个时期这样的东西。

注意:我的古代 C# 版本只有Action<T>(并且没有ActionAction<T, T>等等),所以如果你也被困在那里,你必须为每个方法添加一个虚拟参数才能使用这种方法。

于 2010-04-13T00:36:07.960 回答