0

C# .NET 3.5。我试图了解 C# Action 对象的内在限制。在 lamda(实际上是 lamdas 吗?)中,我们可以执行赋值、调用函数,甚至执行三元运算,但不能执行多语句运算。

这是因为单语句执行只是将其包装在委托中的语法糖吗?为什么下面的第一个示例不起作用?

public class MyClass
{
    private int m_Count = 0;

    public void Test()
    {
        int value = 0;

        // Does not work, throws compile error
        Action action = () => { if(m_Count < 10) m_Count++; value = m_Count; }

        // Works
        Action action2 = () => value = delegate(){ 
            if(m_Count < 10) 
                m_Count++; 

            return m_Count;
        };

        // Works
        Action action3 = () => value = m_Count;

        // Works
        Action action4 = () => value = m_Count < 10 ? m_Count++ : 0;

        // Works
        Action action5 = () => value = Increment();
    }

    public int Increment()
    {
        if (m_Count < 10)
            m_Count++;

        return m_Count;
    }
}

编辑: Grr,对不起噪音。本来,我有

Action action = () => if(m_Count < 10) m_Count++; value = m_Count;

这引发了编译错误,但在发布之前我想我会尝试将它包装在大括号中

Action action = () => { if(m_Count < 10) m_Count++; value = m_Count; }

这也引发了编译错误,所以我得出结论认为这是同样的问题。但是,如果我在大括号后面加上一个分号,它就可以了

Action action = () => { if(m_Count < 10) m_Count++; value = m_Count; };

对不起,噪音!

编辑 2:感谢 cfeduke,您在我上面的编辑同时发布 - 继续并标记为答案。

4

2 回答 2

11

你缺少一个分号,它编译:

 Action action = () => { if (m_Count < 10) m_Count++; value = m_Count; };

当你说type name = statement;你需要一个分号时,即使你对代码块使用大括号。

于 2008-10-24T16:30:30.337 回答
5

cfeduke 已经发布了让您的代码编译的解决方案。

请注意,您不能将语句块 lambda 表达式转换为表达式树,即使您可以将它们转换为委托。对于可以转换为表达式树的内容还有其他限制。

回到委托,那里有一些限制 - 例如,您不能在 lambda 表达式中编写迭代器块。(我以前就想这样做——当你试图理解它时会变得很奇怪。但你不能这样做。)在大多数情况下,你几乎可以做任何你可以在一个方法中做的事情。

于 2008-10-24T16:34:46.787 回答