可以在c#中组合两个动作吗?

时间:2016-11-03 12:33:06

标签: c# lambda

我只是在玩Action来提取lambda表达式。

我有一个布尔变量,根据它的值,我的lambda体应该是不同的。

但是,在这种特殊情况下,区别只是调用另一种不改变返回类型的方法。这就是我所拥有的:

Action<MyType> myLambda;

if (myBooleanCondition)
{
     myLambda = x => x.ChangeBehavior();
}
else
{
     myLambda = x => x.ChangeBehavior().ChangeSize();
}

是否可以将两个lambda定义减少/合并为一个以使其更优雅?

此项目使用C#4.0,但如果在较新版本中进行了简化,请告知我们。

4 个答案:

答案 0 :(得分:8)

可以使用+=运算符来连接委托,您可以使用它来简化您的具体示例。

例如,您可以像这样简化代码:

Action<MyType> myLambda = x => x.ChangeBehavior();

if (!myBooleanCondition)
    myLambda += x => x.ChangeSize();

完整的可编辑示例:

using System;

namespace Demo
{
    class MyType
    {
        public MyType ChangeBehavior()
        {
            Console.WriteLine("ChangeBehavior()");
            return this;
        }

        public void ChangeSize()
        {
            Console.WriteLine("ChangeSize()");
        }
    }

    class Program
    {
        static void Main()
        {
            var x = new MyType();

            test(true)(x);       // Calls ChangeBehavior()
            Console.WriteLine();
            test(false)(x);      // Calls ChangeBehavior() and then ChangeSize()
        }

        static Action<MyType> test(bool myBooleanCondition)
        {
            Action<MyType> myLambda = x => x.ChangeBehavior();

            if (!myBooleanCondition)
                myLambda += x => x.ChangeSize();

            return myLambda;
        }
    }
}

话虽如此,我认为你不应该这样做 - 这太微妙了。您的原始代码没有任何问题!

答案 1 :(得分:5)

完全相同,但可能会给你 更优雅 (这就是问题所在):使用conditional operator(?:) < / p>

Action<MyType> myLambda = myBooleanCondition ? x => x.ChangeBehavior() :
                                               x => x.ChangeBehavior().ChangeSize();

答案 2 :(得分:2)

如果使用缓冲区变量,可以避免else分支,例如

Func<MyType, MyType> ChangeBehavior, func;
func = ChangeBehavior = x => x.ChangeBehavior();

if (!myBooleanCondition)
    func = x => ChangeBehavior(x).ChangeSize();

Action<MyType> myLambda = x => func(x);

答案 3 :(得分:1)

你有什么好。但这里有一些替代方案。

这个为myBooleanCondition变量创建一个闭包。

bool myBooleanCondition = false;

Action<MyType> myLambda = (x) => {
    if (myBooleanCondition)
    {
         x.ChangeBehavior();
    }
    else
    {
         x.ChangeBehavior().ChangeSize();
    }
};

这个允许你传入布尔条件。

Action<MyType, bool> myLambda = (x, condition) => {
    if (condition)
    {
         x.ChangeBehavior();
    }
    else
    {
         x.ChangeBehavior().ChangeSize();
    }
};

这个为myType变量和myBooleanCondition变量创建一个闭包。

bool myBooleanCondition = false;
MyType myType = new MyType();

Action myLambda = () => {
    if (myBooleanCondition)
    {
         myType.ChangeBehavior();
    }
    else
    {
         myType.ChangeBehavior().ChangeSize();
    }
};

代码的最佳选择实际上取决于用例。