Как вы пишете метод расширения 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()" к универсальному типу (т. е."где Т :class, new()" для обеспечения того, чтобы T был одновременно ссылочным типом (class) и имел конструктор без параметров.

Гленн Блок имеет хороший пример реализации 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)
{
  ...
}

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

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

Вот пример для просмотра 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