汎用的に型指定されたクラスの C# 拡張メソッドを作成するにはどうすればよいですか

StackOverflow https://stackoverflow.com/questions/68750

質問

これは単純なものであることが望ましいです。

System.Web.Mvc.ViewPage< T > クラスに拡張メソッドを追加したいと考えています。

この拡張メソッドはどのように見えるべきでしょうか?

私の最初の直感的な考えは次のようなものです。

namespace System.Web.Mvc
{
    public static class ViewPageExtensions
    {
        public static string GetDefaultPageTitle(this ViewPage<Type> v)
        {
            return "";
        }
    }
}

解決

一般的な解決策は次のとおりです この答え.

System.Web.Mvc.ViewPage クラスを拡張するための具体的な解決策は次のとおりです。 私の答え 以下、から始まりました 一般的な解決策.

違いは、特定のケースでは、ジェネリック型のメソッド宣言と、ジェネリック型を参照型として強制するステートメントの両方が必要であることです。

役に立ちましたか?

解決

現在のマシンには VS がインストールされていませんが、構文は次のようになると思います。

namespace System.Web.Mvc
{
    public static class ViewPageExtensions
    {
        public static string GetDefaultPageTitle<T>(this ViewPage<T> v)
        {
            return "";
        }
    }
}

他のヒント

ありがとうございます。それを実行すると、次のエラーが発生しました。

タイプ「tmodel」は、一般的なタイプまたはメソッドのパラメーター「tmodel」として使用するために、参照タイプでなければなりません

それは私に教えてくれました このページ, 、これにより、次の解決策が得られました。

namespace System.Web.Mvc
{
    public static class ViewPageExtensions
    {
        public static string GetDefaultPageTitle<T>(this ViewPage<T> v) 
          where T : class
        {
            return "";
        }
    }
}

関数にジェネリック型指定子が必要なだけです。

namespace System.Web.Mvc
{
    public static class ViewPageExtensions
    {
        public static string GetDefaultPageTitle<Type>(this ViewPage<Type> v)
        {
            return "";
        }
    }
}

編集:ほんの数秒で見逃してしまいました!

namespace System.Web.Mvc
{
    public static class ViewPageExtensions
    {
        public static string GetDefaultPageTitle<T>(this ViewPage<T> view)
            where T : class
        {
            return "";
        }
    }
}

また、「new()」修飾子をジェネリック型に追加する必要がある、または追加したい場合もあります(つまり、"ここで T :class, new()」を使用して、T が参照型 (クラス) であり、パラメーターなしのコンストラクターを持つことを強制します。

グレン・ブロック を実装する良い例があります ForEach への拡張メソッド IEnumerable<T>.

彼から ブログ投稿:

public static class IEnumerableUtils
{
    public static void ForEach<T>(this IEnumerable<T> collection, Action<T> action)
    {
        foreach(T item in collection)
            action(item);
    }
}

指定されたタイプでのみ拡張機能を使用できるようにする場合は、実際のタイプを指定する必要があります。

何かのようなもの...

public static string GetDefaultPageTitle(this ViewPage<YourSpecificType> v)
{
  ...
}

インテリセンスは、一致する型で (この場合) ViewPage を宣言した場合にのみ拡張メソッドを表示することに注意してください。

また、System.Web.Mvc 名前空間は使用しないのが最善です。using セクションに名前空間を含める必要がないのが便利であることはわかっていますが、拡張関数用に独自の拡張名前空間を作成した方がはるかに保守しやすくなります。

Razor ビューの例を次に示します。

public static class WebViewPageExtensions
{
    public static string GetFormActionUrl(this WebViewPage view)
    {
        return string.Format("/{0}/{1}/{2}", view.GetController(), view.GetAction(), view.GetId());
    }

    public static string GetController(this WebViewPage view)
    {
        return Get(view, "controller");
    }

    public static string GetAction(this WebViewPage view)
    {
        return Get(view, "action");
    }

    public static string GetId(this WebViewPage view)
    {
        return Get(view, "id");
    }

    private static string Get(WebViewPage view, string key)
    {
        return view.ViewContext.Controller.ValueProvider.GetValue(key).RawValue.ToString();
    }
}

ジェネリックバージョンは非ジェネリックバージョンを拡張するものであるため、実際にはジェネリックバージョンを使用する必要はありません。そのため、それを非ジェネリック基本クラスに置くだけで完了です:)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top