2011-07-25 8 views
2

VB.NETでのプロパティの名前を返すことができ、コードのシンプルな作品を考える:式ツリー - C#でのアクション<T>に異なるコンパイラ動作とVB.NET

Function NameForProperty(Of T)(ByVal field As Expression(Of Action(Of T))) As String 

    Dim expression = DirectCast(field.Body, MemberExpression) 

    Return expression.Member.Name 

End Function 

次のように動作します。

NameForProperty(Of String)(Function (s) s.Length) ' ==> returns "Length" 

そして私はC#で同等であったであろうと思ったものを:

string NameForProperty<T>(Expression<Action<T>> field) 
{ 
    var expression = (MemberExpression)field.Body; 

    return expression.Member.Name; 
} 

Whを私はC#バージョン呼び出そうとエン:

NameForProperty<string>(s=>s.Length); 

をこれは、コンパイラエラーを返します。

Only assignment, call, increment, decrement, and new object expressions can be used as a statement

私の質問は:2つのコード片の間の違いは何ですか?

EDIT

イワンコードはC#で動作しない理由としてanswerを提供しました。私はまだそれがVB.NETで動作する理由について興味があります。

EDIT#2

明確にするために、私は動作するコードを探していないよ - 単に理由コードはVB.NETではなくC#で動作します。

+2

私は思っています*「アクション MSDNの記事」(http://msdn.microsoft.com/en-us/library/018hxwa8.aspx)の注釈セクションのコメントの可能性があります。具体的には「Visual Basicでは、Sub ... End Sub構文で定義する必要があります。また、無視される値を返すメソッドでもあります。 Visual Basicのように、戻り値は無視されます。おそらく、前にラムダ式で 'Sub'を使用できなかったことが原因でしょうか?私はしばらくの間、.NETで作業していないので、私はここでは外れているかもしれません。 –

+0

これは正しい手掛かりになります。 C#のアクションには戻り値がありません。戻り値のないvoid関数です。ラムダがVB.NETで返すことができる関数であれば、なぜVBで動作するのでしょうか?それは私の答えに 'Action'の代わりに' Func'を使用していた理由です。 – Zebi

答えて

2

ご使用のバージョンの問題は、Action<T>を使用しようとしていることにあります。それは何も返さないので、ラムダのボディ(s.Length)はステートメントでなければなりません。実際には言葉ではありません。だからコンパイラはそれについて不平を言う。

あなたはそれが同じものである

public void A() 
{ 
    string s = "abc"; 
    s.Length; 
} 

を書いたと思います場合は同じように文句を言うでしょう。

私はVB.NETの専門家ではないので、なぜVBで動作しているのか説明できません。申し訳ありません。

+0

あなたの答えをありがとう。私はこのコードに相当するものを見ました。つまり、私はそれを働かせることができます。私の主な質問は、他の構文がVB.NETで有効な場合、C#でこのようにしなければならないのはなぜですか? – user122211

+0

@ user122211:それは答えではありません。 – BoltClock

+0

妥当と思われます。 VB.NETでなぜそれが動作するのか他の誰も説明できない場合、私はあなたの答えを受け入れます。 – user122211

0

Actionの代わりにFuncにメソッドを変更しようとします。

あなたの声明は、エラーが示す通り有効ではありません。アクションをFuncに変更した場合は、Lengthが戻り値なのでOKです。 おそらく、VBコンパイラには他のチェック/要件があります。

+0

Delegate System.Func は引数を1つもとりません – Martin

+0

もちろん、 'Func 'を使用するか、 'Func 'という特殊なタイプを使用して動作させる必要があります。 – Zebi

関連する問題