visual una que programacion polimorfico parametrizado método metodos metodo llamar genérica funciones extensión estática definirse declara debe como clases clase c# asp.net-mvc generics extension-methods

c# - una - que es un metodo en programacion



¿Cómo se escribe un método de extensión C#para una clase de genérico? (7)

Esto debería ser, con suerte, simple.

Me gustaría agregar un método de extensión a la clase System.Web.Mvc.ViewPage <T>.

¿Cómo debería verse este método de extensión?

Mi primer pensamiento intuitivo es algo como esto:

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

Solución

La solución general es esta respuesta .

La solución específica para extender la clase System.Web.Mvc.ViewPage es mi respuesta a continuación, que comenzó a partir de la solución general .

La diferencia radica en el caso específico en que necesita una declaración de método tipado genéricamente Y una declaración para aplicar el tipo genérico como tipo de referencia.


Gracias leddt. Hacer eso produjo el error:

El tipo ''TModel'' debe ser un tipo de referencia para usarlo como parámetro ''TModel'' en el tipo o método genérico

lo que me indicó esta página , que arrojó esta solución:

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


No tengo VS instalado en mi máquina actual, pero creo que la sintaxis sería:

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


Si desea que la extensión solo esté disponible para el tipo especificado, simplemente necesita especificar el tipo real que manejará

algo como...

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

Tenga en cuenta que intellisense solo mostrará el método de extensión cuando declare su (en este caso) ViewPage con el tipo coincidente.

Además, es mejor no utilizar el espacio de nombres System.Web.Mvc, sé que es conveniente no tener que incluir su espacio de nombres en la sección de usos, pero es mucho más fácil de mantener si crea su propio espacio de nombres de extensiones para sus funciones de extensión.


Solo necesita el especificador de tipo genérico en la función:

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

Editar: ¡solo lo extrañé por segundos!


Glenn Block tiene un buen ejemplo de implementar un método de extensión IEnumerable<T> para IEnumerable<T> .

De su publicación en el blog :

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 ""; } } }

También puede necesitar / desear agregar el calificador "nuevo ()" al tipo genérico (es decir, "donde T: clase, nuevo ()" para exigir que T sea tanto un tipo de referencia (clase) como un constructor sin parámetros.


Aquí hay un ejemplo para las vistas de 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(); } }

Realmente no necesita usar la versión genérica ya que la versión genérica amplía la no genérica, así que simplemente póngalo en la clase base no genérica y listo :)