web-dev-qa-db-ja.com

これはどういう意味ですか:Expression <Func <TModel、TValue >>

ASP.Net MVCでは、かみそりのビューで、次の種類のコードを入力できます。

@Html.EditorFor(model => model.Name)

(この場合、モデルのタイプとして定義されているオブジェクトのフィールド名のテキストボックスを作成します)

EditorForメソッドの定義を見ると、次のようになります。

EditorFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression);

だから私は自分でその種のメソッドを実装しようとしましたが、これが何を意味するのか本当にわかりませんExpression<Func<TModel, TValue>>

式とは何か、Func、およびFunc型の式は誰に説明できますか?

私が見つけた説明はすべて抽象的なので、手がかりが得られませんでした...

7
Michel

Expression<T> クラス:

厳密に型指定されたラムダ式を、式ツリーの形式のデータ構造として表します。

および

System.Linq.Expressions名前空間には、言語レベルのコード式を式ツリーの形でオブジェクトとして表すことができるクラス、インターフェイス、および列挙が含まれています。

抽象クラスExpressionは、式ツリーのモデル化に使用されるクラス階層のルートを提供します。

Expressionから派生するこの名前空間のクラス、たとえばMemberExpressionParameterExpressionは、式ツリーのノードを表すために使用されます。 Expressionクラスには、さまざまなタイプの式ツリーノードを作成する静的(Visual Basicでは共有)ファクトリメソッドが含まれています。

列挙型ExpressionTypeは、一意のノードタイプを指定します。


Func<TResult> (および家族)の代表:

このデリゲートを使用すると、カスタムデリゲートを明示的に宣言しなくても、パラメーターとして渡すことができるメソッドを表すことができます。カプセル化されたメソッドは、このデリゲートによって定義されているメソッドシグネチャに対応している必要があります。

ファミリは基本的に、戻り値を持つ関数のデリゲートをカプセル化します。


まとめると、これらは、型付けされたfuncデリゲートを取り、モデルタイプのパラメーターを取り、ラムダが返す値を返す式です。

7
Oded

式は、ラムダ式を取得して構文ツリーに変換できるようにするクラスです。 Linqが(たとえば)Linqクエリを実際のSQLクエリに変換するために使用します。これは非常に拡張性が高いため、他のことを行うことができます。

http://msdn.Microsoft.com/en-us/library/bb335710(v = vs.90).aspx

ASTに慣れていない場合は、 http://en.wikipedia.org/wiki/Abstract_syntax_tree を参照してください。

3
doug65536

HTMLヘルパーは、LINQ to SQLおよびエンティティフレームワークをサポートするために.NETフレームワークに導入された "Static Reflection" と呼ばれるトリックを使用します。基本的に、式は、構文ツリーでコンパイル時に検証されるLambda(したがってStatic)をキャプチャします。ツリーは歩くことができ、ラムダの本体によって参照されるメンバーの名前などを与えることができます。

基本的に、これは、他の一部の言語サポートと同様に、.NETに「シンボル」キーワードがないことに対する回避策です。

2
Michael Brown

この特定の例では、生成されたHTMLは次のようになります。

_<input class="text-box single-line" id="Name" name="Name" type="text" value="ActualName" />
_

パラメータがFuncだけの場合、値ActualNameを取得できますが、アクセスしているプロパティの名前(Name)は取得できません。そのため、その名前を取得するには、stringパラメータ(たとえば、@Html.EditorFor(model => model.Name, "Name")など)として必要になります。

これは、プロパティ名を2回入力する必要があることを意味するため、ニースではありません。さらに悪いことに、コンパイル時の安全性が失われます。プロパティ名が変更されても、2番目のパラメーターでエラーが発生しません。

2
svick