13

I'm just learning C# and MVC, and trying to understand some examples.

@Html.EditorFor(m => m)

Eventually I figured out that '=>' is the lambda operator, and that it means something like "m such that m". That doesn't really make any sense to me. Why not just pass in m?

Also, I don't see m defined in any view that I'm working with. Model is defined, and allegedly that's what this method is picking up. How does that work?

Finally, I looked at the definition for Html.EditorFor, and don't see any overload for passing in just a single parameter. Where is this syntax defined?? http://msdn.microsoft.com/en-us/library/ee834942.aspx

4

4 に答える 4

18

メソッドのシグネチャを調べて、これを分解してみましょう。

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

これは拡張メソッド構文を使用しています。つまり、 という名前のメソッドを追加しEditorForHtmlHelper、呼び出しを行うことができますHtml.EditorFor。しかし、私たちが本当に興味を持っているのは、2 番目のパラメーターですExpression<Func<TModel, TValue>>。これはかなり複雑なパラメーターですが、今のところ、. であるという事実は無視できExpressionます。単純化して、次のことを調べてみましょう。

Func<TModel, TValue> expression

これは、引数が( 型の) 1 つのパラメーターを持つ任意のメソッドでTModelあり、戻り値の型が であることを意味しますTValue。メソッドの(本質的に)より簡潔な表現であるラムダを使用してきましたが、それを通常のメソッドと考えるだけでも役に立ちます。つまり、ラムダはモデルを取得してモデルを返しています。

m => m

これはあまり興味深いものではないので、モデルからプロパティを返すより現実的なシナリオと比較してみましょう。

m => m.MyStringProperty

どこかで宣言した通常の静的メソッドと比較してみましょう。

public static class MyStaticClass 
{
    public static string Foo(TModel model) 
    {
        return model.MyStringProperty;
    }
}

実際にはそうではありませんがTModel、 を介してモデルタイプを宣言したものになります@model。ここで、議論のために、代わりに の呼び出しでこのメソッドを使用することもできますEditorFor

Html.EditorFor(MyStaticClass.Foo);

要約すると、ラムダは (ほとんどの場合) 通常のメソッドの省略形にすぎません。つまり、メソッドを渡すだけです。

ここでの最後の注意点は、実際には式ツリーを使用していることです。つまり、実際にメソッドを渡すのではなく、メソッドのコードを表すオブジェクト モデル (式ツリー) を渡しているということです。これは、本質的に、使用しているプロパティ名を把握するために使用されるだけです (通常、ラムダはm => m.MyProperty単に ではなくに似ているためm => m)。これはすべて、文字列 (つまり、"MyProperty") を使用してプロパティ名を参照するマジック ストリングを回避するためです。

于 2012-05-06T00:29:52.037 に答える
3
  1. あなたの例では、ラムダ関数は何の目的も果たしません。ただし、その実際の用途は、モデルのプロパティのエディターをレンダリングする場合です: @Html.EditorFor(m => m.SomeProperty)。ラムダ式は実際には関数の省略形ですが、デリゲートによって厳密に型指定されています。この概念は、Javascript の方がなじみがあるかもしれません。

    myFunction( function(x) { return x.SomeProperty; });

  2. 「m」は事前定義されていません。ラムダ式の 2 番目の部分のパラメーターに名前を付けています。(名前に関係なく、同じもの、この場合はページのモデルを指します。)

  3. これらの Html.EditorFor の定義に表示される最初のパラメーターは、実際にはパラメーターではありません。thisキーワードを使用して拡張メソッドを定義していることに気付くでしょう。このパラメーターは、メソッドを呼び出したオブジェクト (この場合はHtmlHelper<Model>オブジェクト) を参照します。

于 2012-05-06T00:27:20.027 に答える
2

1.

  • @Html.EditorFor(m => m)- モデル全体のエディタを表示
  • @Html.EditorFor(m => m.propertyName)- モデルの特定のプロパティのエディタを表示

2.

@Html.EditorFor(m => m)@Html.EditorFor(t => t)またはに等しい@Html.EditorFor(randomName => randomName)。名前は関係ありません。それは単なるパラメーターの名前です。このパラメーターの型は、ビュー モデルの型です。

重要なのは値だけではないため、関数を渡す必要があります。リフレクションは、プロパティを表示する方法を説明する属性を取得するために使用されます。この例を見てください

public class ResetPasswordModel
{
    public string Username { get; set; }

    [DataType(DataType.Password)]
    public string NewPassword { get; set; }
    [DataType(DataType.Password)]
    public string PasswordConfirmed { get; set; }
}

属性は、NewPassword が通常の入力ではなく、パスワード フィールドであることを示します。値を渡した場合、それは不可能です。

この例@Html.EditorFor(m => m)では、ユーザー名の 1 つの入力とパスワードの 2 つのパスワード入力が含まれていることを示します。@Html.EditorFor(m => m.NewPassword)パスワードのタイプを持つ入力が表示されます。

3.

http://msdn.microsoft.com/en-us/library/ee402949.aspx

public static MvcHtmlString EditorFor<TModel, TValue>(
    this HtmlHelper<TModel> html,
    Expression<Func<TModel, TValue>> expression
)

HtmlHelper クラスの拡張メソッドです。this HtmlHelper<TModel> htmlパラメータではなく、関数が拡張するクラスの型です。

于 2012-05-06T00:29:02.273 に答える
1

=>演算子は「に行く」を意味すると考えてください。つまり、 (m => m)「m は m に行く」という意味であり、同じことを返す別の言い方ですm

あなたの例では@Html.EditorFor(m => m)、は、拡張メソッドの引数であるmラムダ式 への匿名入力パラメーターです。質問で指摘したように、このメソッドのオーバーロードはどれも、1 つのパラメーターよりも少なくて済みません。これは、これが拡張メソッドであり、最初のパラメーターが拡張する型を示しているためです。2 番目のパラメーターはExpressionであり、これらにはラムダを使用できます。m => mEditorFor

于 2012-05-06T00:28:28.750 に答える