Как написать метод расширения C # для класса с типизированным типом - PullRequest
9 голосов
/ 16 сентября 2008

Надеюсь, это должно быть просто.

Я хотел бы добавить метод расширения в класс System.Web.Mvc.ViewPage .

Как должен выглядеть этот метод расширения?

Моя первая интуитивная мысль примерно такая:

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

Решение

Общее решение: этот ответ .

Конкретным решением для расширения класса System.Web.Mvc.ViewPage является мой ответ ниже, который начинается с общего решения .

Разница заключается в том, что в конкретном случае вам нужно как объявление метода общего типа, так и оператор для принудительного применения универсального типа в качестве ссылочного типа.

Ответы [ 7 ]

17 голосов
/ 16 сентября 2008

У меня нет установленной VS на моей текущей машине, но я думаю, что синтаксис будет:

namespace System.Web.Mvc
{
    public static class ViewPageExtensions
    {
        public static string GetDefaultPageTitle<T>(this ViewPage<T> v)
        {
            return "";
        }
    }
}
5 голосов
/ 16 сентября 2008

Спасибо, leddt. Это привело к ошибке:

Тип 'TModel' должен быть ссылкой введите, чтобы использовать его в качестве параметра 'TModel' в универсальном типе или методе

, который указал мне на эту страницу , которая дала это решение:

namespace System.Web.Mvc
{
    public static class ViewPageExtensions
    {
        public static string GetDefaultPageTitle<T>(this ViewPage<T> v) 
          where T : class
        {
            return "";
        }
    }
}
3 голосов
/ 16 сентября 2008

Для этой функции просто необходим спецификатор общего типа:

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

Редактировать: Просто пропустил его за секунды!

2 голосов
/ 16 сентября 2008
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 является и ссылочным типом (классом) и имеет параметр без параметров конструктор.

1 голос
/ 02 августа 2012

Вот пример для видов 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();
    }
}

Вам действительно не нужно использовать универсальную версию, поскольку универсальная версия расширяет неуниверсальную, поэтому просто поместите ее в неуниверсальный базовый класс, и все готово:)

1 голос
/ 16 сентября 2008

Блок Гленна имеет хороший пример реализации метода расширения 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);
    }
}
1 голос
/ 16 сентября 2008

Если вы хотите, чтобы расширение было доступно только для указанного типа вам просто нужно указать фактический тип, который вы будете обрабатывать

что-то вроде ...

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

Примечание. Intellisense будет отображать метод расширения только тогда, когда вы объявите свой (в данном случае) ViewPage с соответствующим типом.

Кроме того, лучше не использовать пространство имен System.Web.Mvc, я знаю, что удобно не включать ваше пространство имен в раздел использования, но его гораздо удобнее обслуживать, если вы создаете собственное пространство имен расширений для своих функций расширения.

...