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;
}
}
编辑:格尔,对不起噪音。最初,我有
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,你在我上面的编辑的同时发布了 - 继续并标记为答案。
答案 0 :(得分:11)
你缺少一个分号,它编译:
Action action = () => { if (m_Count < 10) m_Count++; value = m_Count; };
当你说type name = statement;
时,你需要一个分号,即使你使用大括号代替代码块。
答案 1 :(得分:5)
cfeduke发布了让你的代码编译的解决方案。
请注意,即使可以将它们转换为委托,也无法将语句块lambda表达式转换为表达式树。您可以将other limitations转换为表达式树。
回到代理,那里有一些限制 - 例如,你不能在lambda表达式中编写迭代器块。 (我之前想要这样做 - 当你试图绕过它时会变得很奇怪。但是你不能这样做。)在大多数情况下,你几乎可以做任何你能用方法做的事情。