Quando dovrei usare l'operatore di conversione di tipo implicito di C #?

13

In C #, possiamo sovraccaricare l'operatore di conversione implicito come questo (esempio da MSDN ) :

struct Digit
{
    /* ... */
    public static implicit operator byte(Digit d)  // implicit digit to byte conversion operator
    {
        /* ... */
    }
}

Quindi, possiamo avere un tipo, un tipo di valore personalizzato , magicamente che si converte in un altro (non correlato) tipo, lasciando il pubblico in disorientamento (finché non scrutano il backstage e vedere l'operatore implicito di conversione, cioè).

Non mi piace lasciare qualcuno che legge il mio codice in disorientamento. Non penso che molte persone lo facciano.

La domanda è: quali sono i casi d'uso dell'operatore di conversione di tipo implicito che non renderà il mio codice molto più difficile da capire?

    
posta Mints97 19.05.2015 - 23:07
fonte

2 risposte

16

Suggerisco solo conversioni implicite tra tipi che rappresentano approssimativamente gli stessi valori in modi diversi. Ad esempio:

  • Diversi tipi di colore come RGB , HSL , HSV e CMYK .
  • Unità diverse per la stessa quantità fisica ( Meter rispetto a Inch ).
  • Sistemi di coordinate differenti (polar vs cartesiano).

Tuttavia, ci sono alcune linee guida forti che indicano quando non è appropriato per definire una conversione implicita:

  • Se la conversione causa una perdita significativa di precisione o intervallo, non dovrebbe essere implicito (ad es. da float64 a float32 o da long ad int).
  • Se la conversione può generare un'eccezione ( InvalidCast ), non dovrebbe essere implicita.
  • Se la conversione causa un'allocazione dell'heap ogni volta che viene eseguita, non dovrebbe essere implicita.
  • Se la conversione non è un'operazione O(1) , non dovrebbe essere implicita.
  • Se il tipo di origine o il tipo di destinazione è modificabile, la conversione non dovrebbe essere implicita.
  • Se la conversione dipende da qualche tipo di contesto (database, impostazioni cultura, configurazione, file system, ecc.), non dovrebbe essere implicito (in questo caso sconsigliamo anche un operatore di conversione esplicito).

Ora dì che il tuo operatore di conversione f: T1 -> T2 non viola nessuna delle regole precedenti, quindi il seguente comportamento indica chiaramente che la conversione può essere implicita:

  • Se a == b poi f(a) == f(b) .
  • Se a != b poi f(a) != f(b) .
  • Se a.ToString() == b.ToString() poi f(a).ToString() == f(b).ToString() .
  • Ecc. per altre operazioni definite su T1 e T2 .
risposta data 20.05.2015 - 01:22
fonte
6

The question is, what are the use-cases of the implicit type conversion operator which won't render my code much more difficult to understand?

Quando i tipi non sono non correlati (ai programmatori). Ci sono (rari) scenari in cui si hanno due tipi non correlati (per quanto riguarda il codice), che sono effettivamente correlati (per quanto riguarda il dominio o programmatori ragionevoli).

Ad esempio, un codice per eseguire la corrispondenza delle stringhe. Uno scenario comune è quello di trovare una stringa letterale. Anziché chiamare IsMatch(input, new Literal("some string")) , una conversione implicita ti consente di sbarazzarti di quella cerimonia - il rumore nel codice - e di concentrarti sulla stringa letterale.

La maggior parte dei programmatori vedrà IsMatch(input, "some string") e intuirà rapidamente cosa sta succedendo. Rende il tuo codice più chiaro al sito di chiamata. In breve, rende un po 'più facile capire che cosa sta succedendo , a scapito di come sta succedendo.

Ora, potresti sostenere che un semplice sovraccarico di funzione per fare la stessa cosa sarebbe meglio. E questo è. Ma se questo genere di cose è onnipresente, avere una conversione è più pulito (meno codice, maggiore coerenza) rispetto a una pila di sovraccarichi di funzioni.

E potresti obiettare che è meglio richiedere ai programmatori di creare esplicitamente il tipo intermedio in modo che vedano "cosa sta realmente accadendo". Questo è meno semplice. Personalmente, penso che l'esempio di stringa letterale sia molto chiaro su "cosa sta realmente succedendo" - il programmatore non ha bisogno di conoscere la meccanica di come succede tutto. Sai come tutto il tuo codice viene eseguito dai vari processori su cui gira il tuo codice? C'è sempre una linea di astrazione in cui i programmatori smettono di preoccuparsi di come qualcosa funziona. Se ritieni che i passaggi di conversione impliciti siano importanti, non utilizzare la conversione implicita. Se pensi che siano solo una cerimonia per mantenere il computer felice, e il programmatore starebbe meglio senza vedere quel rumore ovunque, quindi consideralo.

    
risposta data 19.05.2015 - 23:54
fonte

Leggi altre domande sui tag