C # Stringa di sovraccarico dell’operatore

G’Day Mates –

Qual è il modo corretto (escludendo l’argomento se è consigliabile) di sovraccaricare gli operatori stringa , =?

L’ho provato in cinque modi alla domenica e ho ricevuto vari errori: il mio colpo migliore è stato dichiarare una class parziale e sovraccarico da lì, ma non funzionerà per qualche motivo.

namespace System { public partial class String { public static Boolean operator <(String a, String b) { return a.CompareTo(b) (String a, String b) { return a.CompareTo(b) > 0; } } 

}

String è una class sigillata. Non puoi ereditare da esso, e senza la fonte originale di String, non puoi compilare una sua class parziale. Anche se hai messo le mani sul sorgente (è ansible tramite Reflector o tramite download di simboli di Visual Studio) avresti ancora problemi, dato che è un cittadino di prima class in fase di esecuzione.

Hai davvero bisogno di come operatori sulla stringa? Se è così … perché non usare solo i metodi di estensione ?

 public static bool IsLessThan(this string a, string b) { return a.CompareTo(b) < 0; } public static bool IsGreaterThan(this string a, string b) { return a.CompareTo(b) > 0; } // elsewhere... foo.IsLessThan(bar); // equivalent to foo < bar 

Non c’è modo di sostituire alcun comportamento integrato del compilatore con il proprio. Non è ansible ignorare gli operatori incorporati esistenti per confronti, conversioni, aritmetica e così via. Questo è di design; è così che qualcuno può leggere il tuo codice e sapere che int x = M(); int y = x + 2; int x = M(); int y = x + 2; esegue l’aritmetica intera, al contrario di, ad esempio, la formattazione del disco rigido.

Puoi spiegare perché vuoi farlo? Forse c’è un modo migliore per fare ciò che vuoi.

La semplice risposta è che non puoi; non c’è modo di modificare gli operatori per un’altra class. Le classi parziali sono consentite solo per le classi dichiarate partial in tutti i file e definite nello stesso assembly .

Intendi la class System.String ? Questo è imansible in C #. Non è ansible aggiungere operatori di estensioni a una class esistente. È una caratteristica molto richiesta però.

  • Non è ansible avere una class parziale per la stringa, perché la class stringa stessa non è parziale e quindi non funzionerà con la class parziale.

  • La stringa è sigillata, quindi è ansible ereditarla e quindi sovraccaricare l’operatore.

In breve, purtroppo, non puoi fare quello che devi fare.

Non so cosa stai cercando di fare esattamente, non posso suggerire una buona alternativa. Ma, dai un’occhiata ai metodi di estensione , che sono spesso buoni per le situazioni. Lasciando da parte se è necessario :), è ansible aggiungere alla class stringa un metodo chiamato IsGreaterThan e restituire true o false come si desidera. Ciò è positivo perché è ansible attribuire al metodo di estensione un nome che ne rende chiaro il significato, mantiene intatti gli operatori esistenti (di cui non si ha comunque scelta) e consente un codice semplice / rapido.

Non è ansible sovraccaricare direttamente l’operatore> = e <=, ma è possibile ottenere lo stesso risultato sovraccaricando> e il == separatamente.

Il tuo codice mi sembra corretto, tranne il fatto che ti manca l’overloading per ==.

Sembra che mi sia sbagliato, tuttavia, puoi sempre tornare alla riflessione. Penso che se fai un po ‘di scavo e di hacking, puoi farlo funzionare con la riflessione per estendere la class poiché reflection consente di aggiungere funzioni o scambiare corpi di funzioni in fase di runtime.

Che sia consigliabile e buona pratica, ne dubito. C’è una ragione per cui la class è sigillata. Fare la cosa che ho menzionato può portare a comportamenti non definiti in alcune circostanze a causa di alcune ipotesi che il framework .net fa sulle stringhe. Le probabilità sono grandi che la class di stringhe crolli internamente.