24

次の文字列拡張メソッドが与えられた場合

namespace JHS.ExtensionMethods
{
  public static class StringExtensions
  {
    public static string ToUSAPhone(this String str)
    {
      return String.Format("{0:(###) ###-####}", Double.Parse(str));
    }
  }
}

@using ステートメントが MVC4 Razor ビューに追加されました

@using JHS.ExtensionMethods;

次の文字列値は拡張メソッドを呼び出します

@Model.producer.phone.ToUSAPhone()

次のエラーが発生します

'string' does not contain a definition for 'ToUSAPhone'

また、名前空間を /Views フォルダーの web.config に入れてみましたが、同じエラーが発生しました。

<pages pageBaseType="System.Web.Mvc.WebViewPage">
  <namespaces>
    <add namespace="System.Web.Mvc" />
    <add namespace="System.Web.Mvc.Ajax" />
    <add namespace="System.Web.Mvc.Html" />
    <add namespace="System.Web.Optimization"/>
    <add namespace="System.Web.Routing" />
    <add namespace="JHS.ExtensionMethods"/>
  </namespaces>
</pages>

同じ呼び出しを C# クラスに入れて、拡張メソッドが機能することを確認しました。

string test=producer.phone.ToUSAPhone();

拡張メソッドへの参照は MVC4 Razor ビューでは利用できないようですが、理由がわかりませんか?

4

5 に答える 5

38

これは、拡張メソッドを使用しようとしている型が実際にはdynamic. CSharp RuntimeBinder によって例外が生成されているかどうかを確認します。その場合は、メソッドを共通または庭の静的メソッドとして使用できます。

@StringExtensions.ToUSAPhone(Model.producer.phone)

または、値を文字列にキャストできます。

@(((string)Model.producer.phone).ToUSAPhone())

Eric Lippert (元 MSFT) によると:

ダイナミクスが拡張型をサポートしないという事実の背後にある理由は、通常の非動的コード拡張メソッドは、一致する拡張メソッドを持つ静的クラスのコンパイラに認識されているすべてのクラスを完全に検索することによって機能するためです。検索は、名前空間のネストと、各名前空間で使用可能な "using" ディレクティブに基づいて順番に行われます。

つまり、動的拡張メソッドの呼び出しを正しく解決するために、DLR は実行時に、すべての名前空間のネストと "using" ディレクティブがソース コードに含まれていたことを何らかの方法で認識しなければなりません。そのすべての情報を呼び出しサイトにエンコードするのに便利なメカニズムはありません。

于 2013-10-08T19:55:50.830 に答える
0

これにはさらに別のささいな理由があるかもしれませんが、それは私に起こりました.

拡張機能を作成したファイルには、VS ファイル プロパティ ペインのビルド アクション プロパティの値として「コンテンツ」がありました。

「コンパイル」に切り替えると、当然、問題はすぐに修正されました...

于 2018-10-31T22:17:54.170 に答える