2008-09-16 10 views
8

Cela devrait être une opération simple.Comment écrire une méthode d'extension C# pour une classe générique

Je voudrais ajouter une méthode d'extension à la classe T> System.Web.Mvc.ViewPage <.

À quoi devrait ressembler cette méthode d'extension?

Ma première pensée intuitive est quelque chose comme ceci:

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

Solution

La solution générale est this answer.

La solution spécifique à l'extension de la classe System.Web.Mvc.ViewPage est my answer ci-dessous, qui a démarré à partir de general solution. La différence est dans le cas spécifique où vous avez besoin à la fois d'une déclaration de méthode générique et d'une instruction pour appliquer le type générique en tant que type de référence.

Répondre

16

Je n'ai pas VS installé sur ma machine actuelle, mais je pense que la syntaxe serait:

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

Voir http: // stackoverflow .com/questions/68750/how-do-vous-écrivez-ac-extension-méthode-pour-un-typically-typed-class/68802 # 68802 –

3

Il a juste besoin du prescripteur de type générique sur la fonction:

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

Modifier : Juste raté en quelques secondes!

5

Merci leddt. faire qui a abouti à l'erreur:

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

qui me montra this page, qui a abouti à cette solution:

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

Si vous souhaitez que l'extension ne sera disponible que pour le type spécifié vous tout simplement besoin pour spécifier le type réel que vous allez traiter

quelque chose comme ...

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

Remarque intellisense affichera uniquement la méthode d'extension lorsque vous déclarez votre (dans ce cas) ViewPage avec le type correspondant. Aussi, mieux vaut ne pas utiliser l'espace de noms System.Web.Mvc, je sais qu'il est pratique de ne pas inclure votre espace de noms dans la section des articles, mais c'est beaucoup plus facile à gérer si vous créez votre propre espace de noms pour vos fonctions d'extension .

1

Glenn Block a un bon exemple d'implémentation d'une méthode d'extension ForEach à IEnumerable<T>.

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

Vous pouvez aussi avoir besoin/souhaitez ajouter le "nouveau()" qualification du type générique (ie "où T: classe, nouvelle()" à appliquer que T est à la fois un type de référence (classe) et un constructeur parameterless

1

Voici un exemple pour une vue 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(); 
    } 
} 

Vous n'avez vraiment pas besoin d'utiliser la version générique car la version générique étend la version non générique, placez-la simplement dans la classe de base non générique et vous avez terminé :)

+0

Neat - acclame pour poster la mise à jour. –