Надеюсь, это должно быть просто.
Я хотел бы добавить метод расширения к классу 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 "";
}
}
}
Ему просто нужен спецификатор универсального типа для функции:
namespace System.Web.Mvc
{
public static class ViewPageExtensions
{
public static string GetDefaultPageTitle<Type>(this ViewPage<Type> v)
{
return "";
}
}
}
Обновлено: просто пропустил секунды!
Спасибо, leddt. Это привело к ошибке:
The type 'TModel' must be a reference type in order to use it as parameter 'TModel' in the generic type or method
который указал мне на эта страница, который дал следующее решение:
namespace System.Web.Mvc
{
public static class ViewPageExtensions
{
public static string GetDefaultPageTitle<T>(this ViewPage<T> v)
where T : class
{
return "";
}
}
}
Если вы хотите, чтобы расширение было доступно только для указанного типа вам просто нужно указать фактический тип, который вы будете обрабатывать
что-то вроде...
public static string GetDefaultPageTitle(this ViewPage<YourSpecificType> v)
{
...
}
Обратите внимание, что intellisense будет отображать метод расширения только тогда, когда вы объявляете свою (в данном случае) ViewPage с соответствующим типом.
Кроме того, лучше не использовать пространство имен System.Web.Mvc, я знаю, что удобно не включать свое пространство имен в раздел использования, но его гораздо удобнее поддерживать, если вы создаете собственное пространство имен расширений для своих функций расширения.
Гленн Блок имеет хороший пример реализации метода расширения 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);
}
}
namespace System.Web.Mvc
{
public static class ViewPageExtensions
{
public static string GetDefaultPageTitle<T>(this ViewPage<T> view)
where T : class
{
return "";
}
}
}
Вам также может потребоваться / пожелать добавить квалификатор «new ()» к универсальному типу (например, «where T: class, new ()», чтобы обеспечить, что T является как ссылочным типом (классом), так и имеет конструктор без параметров.
Вот пример представлений 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();
}
}
Вам действительно не нужно использовать универсальную версию, поскольку общая расширяет неуниверсальную версию, поэтому просто поместите ее в неуниверсальный базовый класс, и все готово :)
См. stackoverflow.com/questions/68750/…