有条件地使用运营商(不是在谈论?:)

时间:2017-04-21 22:52:31

标签: c#

由于这是一个尴尬的问题,答案可能已经存在,但我无法轻易找到答案。所以,如果确实存在,请提前抱歉。

鉴于某些条件,我想更改使用的运算符。例如,我现在在触发事件时添加或删除函数调用,类似于

private void Register(bool add)
{
    if(!add)
    {
        eventA += func1;
        ...
        eventZ += func26;
    }
    else
    {
        eventA -= func1;
        ...
        eventZ -= func26;
    }
}

理想情况下,我想要的是类似的东西,

private void Register(bool add)
{
    operator op = (!add ? += : -=);

    eventA op func1;
    ...
    eventZ op func26;
}

(显然不会这样做,但因此问题)是否有可能有条件地改变所使用的运算符?

2 个答案:

答案 0 :(得分:1)

鉴于“更准确的情况”,一个简单的lambda似乎仍然是最简单的解决方案(尽管确保它对你的用例来说不是太贵):

private void Register(bool add)
{
    Func<int, int, int> op = (add ? (a, b) => a + b : (a, b) => a - b);

    m_A = op(m_A, func1);
    ...
    m_Z = op(m_Z, func26);
}

(您可能需要对语法进行一些更改,我现在无法验证代码;可能需要一些额外的括号或显式转换或其他内容)

赋值本身不容易替换,因为lambdas不支持引用参数;没有办法只做op(ref m_A, func1),这对你要做的事情最有用。如果您不需要这些函数是匿名的,您可以简单地使用辅助方法:

private static void applyOp(ref int a, int b, bool add)
{
  if (add) a += b; else a -= b;
}

private void Register(bool add)
{   
    applyOp(ref m_A, func1, add);
    ...
    applyOp(ref m_Z, func26, add);
}

答案 1 :(得分:1)

我认为你的伪代码最简单地翻译成C#就是用适当的参数定义delegate。对于+=-=操作,使用ref参数可以实现此功能,但您可以定义所需的任何类型的参数。

public delegate void Op(ref int evnt, int fnc);

private void Register(bool add)
{
    Op op = add
        ? new Op((ref int evnt, int fnc) => evnt += fnc)
        : new Op((ref int evnt, int fnc) => evnt -= fnc);

    op(ref eventA, func1);
    op(ref eventB, func2);
    ...
    op(ref eventZ, func26);
}

应该注意的是,这个特定的例子可以用简单的数学解决。

private void Register(bool add)
{
    int mult = add ? 1 : -1

    eventA += mult * func1;
    eventB += mult * func2;
    ...
    eventZ += mult * func26;
}