2009-05-22 2 views
88

Ci sono state occasioni in cui vorrei sovrascrivere un metodo in una classe con un metodo di estensione. C'è un modo per farlo in C#?C'è un modo in C# per sovrascrivere un metodo di classe con un metodo di estensione?

Ad esempio:

public static class StringExtension 
{ 
    public static int GetHashCode(this string inStr) 
    { 
     return MyHash(inStr); 
    } 
} 

un caso in cui ho voluto fare questo è quello di essere in grado di memorizzare un hash di una stringa in un database e che hanno lo stesso valore essere usato da tutte le classi che usa l'hash della classe string (es. Dizionario, ecc.) Poiché l'algoritmo di hashing .Net integrato non è garantito per essere compatibile da una versione del Framework al successivo, voglio sostituirlo con il mio.

Ci sono altri casi in cui mi sono imbattuto dove vorrei sovrascrivere un metodo di classe con un metodo di estensione e quindi non è solo specifico per la classe di stringa o il metodo GetHashCode.

So che potrei farlo con la sottoclasse di una classe esistente, ma sarebbe utile poterlo fare con un'estensione in molti casi.

+0

Poiché un dizionario è una struttura di dati in memoria , che differenza fa se l'algoritmo di hashing cambia dalla versione del framework a quella successiva? Se la versione del framework cambia, ovviamente l'applicazione è stata riavviata e il dizionario è stato ricostruito. –

risposta

83

No; un metodo di estensione non ha mai la priorità su un metodo di istanza con una firma appropriata e non partecipa mai al polimorfismo (GetHashCode è un metodo virtual).

+0

"... non partecipa mai al polimorfismo (GetHashCode è un metodo virtuale)" Potresti spiegare in un altro modo perché un metodo di estensione non potrebbe mai partecipare al polimorfismo perché è virtuale? Ho problemi nel vedere la connessione con queste due affermazioni. – Alex

+3

@Alex citando il virtuale sto semplicemente chiarendo cosa significa essere polimorfico. In praticamente tutti gli usi di GetHashCode, il tipo concreto è sconosciuto, quindi il polimorfismo è in gioco. Pertanto, i metodi di estensione non sono d'aiuto ** anche se hanno la priorità ** nel compilatore regolare. Ciò che l'OP vuole davvero è la patch per le scimmie. Quale C# e .net non facilitano. –

+3

Ciò è triste, in C# così tanti metodi fuorvianti non-sense, come per es. '.ToString()' negli array. È sicuramente una caratteristica necessaria. –

6

Se il metodo ha una firma diversa, è possibile farlo, quindi nel tuo caso: no.

Altrimenti, è necessario utilizzare l'ereditarietà per fare ciò che si sta cercando.

2

Per quanto ne so la risposta è no, perché un metodo di estensione non è un'istanza. È più simile a una struttura intellisense per me che consente di chiamare un metodo statico utilizzando un'istanza di una classe. Penso che una soluzione al tuo problema possa essere un intercettore che intercetta l'esecuzione di un metodo specifico (es. GetHashCode()) e fare qualcos'altro. Per usare un intercettore (come quello fornito da Progetto Castello) tutti gli oggetti dovrebbero essere istanziati usando una fabbrica di oggetti (o un contenitore IoC in Castle) in modo che le loro interfacce possano essere intercettate attraverso un proxy dinamico generato in runtime. (Caslte consente anche di intercettare membri virtuali di classi)