0

C# .NET 3.5。C# Action オブジェクトの本質的な制限を理解しようとしています。ラムダ (実際にはラムダですか?) 内では、代入を実行したり、関数を呼び出したり、3 項演算を実行したりすることもできますが、複数ステートメントの演算を実行することはできません。

これは、単一ステートメントの実行がデリゲートでラップするための単なる構文糖衣であるためですか? 以下の最初の例が機能しないのはなぜですか?

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; };

お騒がせしてすみません!

EDIT 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 は、コードをコンパイルするためのソリューションを投稿しました。

ステートメント ブロックのラムダ式をデリゲートに変換することはできますが、式ツリーに変換することはできないことに注意してください。式ツリーに変換できるものには、他にも制限があります。

デリゲートに戻ると、いくつかの制限があります。たとえば、ラムダ式内にイテレータ ブロックを記述できません。(私は今までそれをしたいと思っていました - 頭を丸めようとすると奇妙になります. しかし、それはできません.) ほとんどの場合、メソッドでできることはほとんど何でもできます.

于 2008-10-24T16:34:46.787 に答える