2008-09-16 13 views
8

Se espera que esta sea una simple.¿Cómo se escribe un método de extensión C# para una clase genéricamente escrita

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

¿Cómo debe 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 this answer.

La solución específica para extender la clase System.Web.Mvc.ViewPage es my answer a continuación, que comenzó desde general solution.

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

Respuesta

16

no me he VS instalado en mi equipo 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 ""; 
     } 
    } 
} 
+0

Consulte http: // stackoverflow .com/questions/68750/how-do-you-write-ac-extension-method-for-a-generic-typed-class/68802 # 68802 –

3

Sólo necesita el especificador de tipo genérico de la función:

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

Editar : ¡Lo perdí por segundos!

5

Gracias leddt. haciendo que produjo el error:

The type 'TModel' must be a reference type in order to use it as parameter 'TModel' in the generic type or method

que me señaló a this page, que produjo esta solución:

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

si desea que la extensión sea sólo está disponible para el tipo especificado que simplemente necesita para especificar el tipo real que será el manejo de

algo así como ...

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

Nota 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 usar el espacio de nombres System.Web.Mvc, sé 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 .

1

Glenn Block tiene un buen ejemplo de implementación de un método de extensión ForEach en IEnumerable<T>.

Desde su blog post:

public static class IEnumerableUtils 
{ 
    public static void ForEach<T>(this IEnumerable<T> collection, Action<T> action) 
    { 
     foreach(T item in collection) 
      action(item); 
    } 
} 
2
namespace System.Web.Mvc 
{ 
    public static class ViewPageExtensions 
    { 
     public static string GetDefaultPageTitle<T>(this ViewPage<T> view) 
      where T : class 
     { 
      return ""; 
     } 
    } 
} 

También puede ser necesario/desea añadir el "nuevo()" calificador de tipo genérico (es decir, "donde T: clase, nueva()" para hacer cumplir que T es a la vez un tipo de referencia (clase) y tiene un constructor sin parámetros

1

Aquí hay un ejemplo para las vistas de la maquinilla de afeitar:.

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 colóquela en la clase base no genérica y listo :)

+0

Limpio - aplausos por publicar la actualización. –

Cuestiones relacionadas