2011-01-11 15 views
9
public static class MyClass 
{ 
    public static void Add<T>(this List<T> list, T item) 
    { 
     list.Add(item); 
     Console.WriteLine(item.ToString()); 
    } 
} 

poiCome nascondere un metodo membro da un metodo di estensione

List<string> list = new List<string>(){"1","2"}; 
list.Add("3"); 

Ma il metodo membro sarebbe chiamato.

C'è comunque il modo di chiamare il mio Extension Method in questo modo?

Non voglio chiamarlo in questo modo:

MyClass.Add(list, item) 
+1

Anche se 'list.Add (" 3 ")' ha sovrascritto 'List.Add' e ha chiamato il metodo di estensione, dovresti aspettarti' list.Add (item) 'per fare lo stesso, ottenendo una ricorsione infinita. – Kobi

+0

Vedo, la mia domanda è solo una questione di curiosità e fornisco un codice di esempio solo per mostrare quello che voglio, tuttavia hai ragione il ploymorphism –

risposta

8

Non è possibile. I metodi di istanza sempre hanno la precedenza sui metodi di estensione, assumendo che siano applicabili. La risoluzione dei membri prenderà in considerazione solo i metodi di estensione una volta che non è riuscito a trovare un'opzione di metodo non di estensione.

Suggerisco di rinominare semplicemente il metodo, a meno che il punto fosse chiamare questo metodo in modo trasparente con il codice esistente.

Se hai fatto prendere un IList<T> invece di List<T>, è possibile creare un tipo di involucro che implementa IList<T> e delegati di tutte le chiamate sulla lista avvolto, si svolgono operazioni in più, come si va. Potresti quindi anche scrivere un metodo di estensione a IList<T> che ha creato il wrapper, il che consentirebbe in alcuni casi una sintassi più fluente. Personalmente preferisco l'approccio wrapper per derivare un nuovo tipo di raccolta, in quanto significa che puoi usarlo con le tue raccolte esistenti, rendendo le modifiche del codice potenzialmente più piccole ... ma tutto dipende da cosa stai cercando di fare.

+1

decoratore ha davvero senso –

7

metodi di istanza sempre avere la precedenza su metodi di estensione, così no.

Il corretta cosa da fare qui sembrerebbe essere polimorfismi - ma nota che List<T> non fornisce virtual metodi. Collection<T>, tuttavia:

using System; 
using System.Collections.ObjectModel; 
class MyClass<T> : Collection<T> { 
    protected override void InsertItem(int index, T item) { 
     base.InsertItem(index, item); 
     Console.WriteLine("Added:" + item.ToString()); 
    } 
    protected override void SetItem(int index, T item) { 
     base.SetItem(index, item); 
     Console.WriteLine("Set (indexer):" + item.ToString()); 
    } 
    // see also ClearItems and RemoveItem 
} 
+2

- è un sovraccarico subdolo? ;) –

+0

@Mitch - nice; p Risolto. –

+0

ma l'overloading è anche chiamato 'polimorfismo ad hoc ', niente di sbagliato con quello –

Problemi correlati