Quanto lontano dovrebbe 'var' e operatore a coalescenza nulla '??' essere intrattenuti senza ostacolare la leggibilità?

23

So che il titolo della domanda è molto soggettivo, ma sono stato confrontato con l'utilizzo dell'operatore ?? da parte dei miei colleghi, dove allo stesso tempo non ero molto contento / a mio agio nell'applicare var in nuove attività codice in arrivo.

L'argomento fornito per l'utilizzo dell'operatore ?? era, elimina la leggibilità nel codice.

La mia domanda è, non succede la stessa cosa quando inizi a usare var ?

    
posta Numan 16.03.2011 - 10:40
fonte

7 risposte

53

Operatore coalescente Null (??)

Personalmente, non vedo nessun aspetto negativo nell'usare questo operatore. Considera i seguenti tre esempi di codice, dai nuovi operatori "facili" a quelli "complessi".

Senza magia:

bool isNameSet = false;
string name;
if ( isNameSet )
{
    Console.WriteLine( name );
}
else
{
    Console.WriteLine( "No name set." );
}

Operatore ternario:

bool isNameSet = false;
string name;
Console.WriteLine( isNameSet ? name : "No name set." );

coalescenza nulla:

string name = null;
Console.WriteLine( name ?? "No name set." );

Il motivo per cui questi operatori sono stati inventati è perché rappresentano operazioni di programmazione molto comuni . Non volerlo usare perché non ci si abitua è solo essere testardi . Le lingue evolvono, le caratteristiche evolvono, impara a usarle!

var keyword

Ho un'opinione in qualche modo diversa sulla parola chiave var. Il tipo di una variabile spesso fornisce informazioni aggiuntive sul tuo codice. Trovo che nascondere il tipo utilizzando la parola chiave var a volte rende il codice meno leggibile. Conoscere meno cosa aspettarsi senza utilizzare il completamento automatico o passare con il mouse sugli identificatori per vedere cosa sono in realtà. A mio parere, questo risulta in un codice che è più lento da leggere / scrivere.

Uso la parola chiave quando trovo che il tipo non fornisce molte informazioni extra.

  • Principalmente in foreach loop , che ho imparato da Resharper poiché è un'impostazione lì. La maggior parte delle volte, sai quale tipo di raccolta stai attraversando, quindi sai che ti aspetti elementi all'interno di quella raccolta.
  • Query Linq . Il risultato delle query linq sono spesso tipi generici molto complessi. La visualizzazione di questo tipo fa più male che bene.
  • nomi di caratteri lunghi che sono semplicemente inizializzati con il loro costruttore. Puoi già dire che cos'è il tipo guardando il costruttore.

Come esempio per l'ultima affermazione:

ThisIsSomeSpecializedTypeRightHere duplication =
    new ThisIsSomeSpecializedTypeRightHere();
var justAsReadable =
    new ThisIsSomeSpecializedTypeRightHere();  // Less duplication.

// But I still prefer the following ...
int number = 9;
SomeCreatedType foo = Factory.CreateSomeType();
    
risposta data 16.03.2011 - 13:15
fonte
16

var consente un codice meno dettagliato, che aumenta la leggibilità. Secondo me, la leggibilità non dovrebbe essere misurata dal numero di dettagli che vedi, ma quanti dettagli sono nascosti a prima vista. Oltre agli esempi di Linq, var consente la digitazione anatra a livello di codice sorgente, dato il seguente esempio:

...
foreach (var message in messages) {
  var label = Factory.CreateLabel();
  label.Text = message;
  Controls.Add(label);
}
...

A chi importa quale sia il tipo di etichetta purché fornisca la proprietà Text?

    
risposta data 16.03.2011 - 15:37
fonte
16

Non ho commenti seri sull'operatore ?? , poiché non ho mai usato un linguaggio con un operatore così pesante. Per quanto riguarda var , le persone programmano in linguaggi come Ruby, Python, Perl e PHP che hanno sempre una digitazione completamente implicita. I nativi di questi linguaggi si rendono conto che il tipo formale di una variabile è di solito un rumore irrilevante. Sei più interessato a ciò che la variabile può fare , ad esempio all'interfaccia strutturale / anatra.

Analogamente, programma principalmente in D. D è tipizzato staticamente ma ha la parola chiave auto , che equivale a var . È considerato idiomatico utilizzarlo ovunque, a meno che non si veda una specifica esigenza di enfatizzare il tipo di qualcosa per il lettore o (tramite conversione implicita) il compilatore. Tranne che occasionalmente quando usato come funzione return type (questo è permesso in D), non l'ho mai trovato in grado di ostacolare la leggibilità, perché per lo più penso in termini di interfacce strutturali / di anatra, non di tipo formale / nominativo, quando programmo.

Inoltre, IMHO che utilizza var ovunque possibile è un buon esempio di DRY. Il tipo di qualcosa dovrebbe essere specificato in un solo posto, e quindi automaticamente essere propagato ogni volta che deve essere propagato. Se si utilizza var e il tipo formale della variabile deve essere modificato, le modifiche necessarie verranno automaticamente propagate ovunque necessarie dal compilatore a condizione che il programma sia ancora corretto per il tipo, piuttosto che il programmatore che deve manualmente cambia ogni istanza. Questa è una buona cosa (TM).

    
risposta data 16.03.2011 - 21:02
fonte
13

Penso che questa sia una domanda per la squadra alla fine. Se non è leggibile da nessun altro sul mio team, non lo userò, anche se potrei provare un paio di volte a convincerli con degli esempi, o sottolineando abbreviazioni analoghe (come + =) che trovano più leggibili.

Tuttavia, se lavori da solo, trovo ?? e var eminentemente leggibili senza limiti. Anche

var a = b ?? c ?? d ?? e ?? "";

per me è abbastanza chiaro.

Gli operatori ternari e dynamic sono una questione diversa, ovviamente.

    
risposta data 16.03.2011 - 11:40
fonte
10

The argument given for using ?? operator was, it takes away readability in code.

Pensandoci brevemente, questo commento mi dice che la persona che ha fatto il commento, non la capisce come dovrebbe. Probabilmente è vero in certe situazioni, ma nel complesso, non faccio sconti su qualcosa che il team C # ha ritenuto importante aggiungere a causa della "leggibilità". Metto questo nella stessa categoria di    if(boolean_object) rispetto a if(boolean_object == true) . Alcune persone sostengono che il secondo è più leggibile, ma in realtà si tratta solo di aggiungere codice aggiuntivo per qualcuno da leggere / digitare, e in alcune situazioni può essere più confuso (pensa if(boolean_object != false) )

My question is, doesn't the same thing happens when you start using var?

Il team C # ti ha permesso di non definire qualcosa che sai cosa sarà. A meno che non sia assolutamente necessario definire quale sarà una variabile (o è assolutamente importante che un oggetto di ritorno sia di tipo x, o che non sia realmente leggibile), io uso var . var x = "MY_STRING"; So che è una stringa dal guardarlo. In verità, non mi interessa davvero che sia una stringa finché fa quello che mi serve. La definizione del tipo di variabile è a mio vantaggio, non del compilatore. Se qualcosa non va, il compilatore mi dirà quando viene eseguito se ho il tipo di variabile sbagliato.

    
risposta data 16.03.2011 - 15:14
fonte
0

La parola chiave var è, a mio avviso, meglio utilizzata nelle situazioni per cui è stata introdotta in origine: query LINQ. In queste query, il tipo di risultato restituito ha spesso un nome molto complesso che è difficile determinare in anticipo e non aiuta la comprensione del lettore su cosa fa il codice.

Tuttavia, facendo var text = "Some text " + variableName + "some more text." è solo pigro.

EDIT: @Jorg Hai saltato su una risposta volutamente semplicistica ma non hai aggiunto nulla alla discussione. OK, che ne dici di questo per un esempio migliore: var items = doc.DocumentElement.FirstChild.ChildNodes; Se riesci a capire il tipo da cui ti darò un cookie.

    
risposta data 16.03.2011 - 13:20
fonte
0

Ho un problema fondamentale con l'utilizzo di var.

In questo esempio tutto è affiancato, ma il problema è in realtà con soluzioni di grandi dimensioni con librerie o progetti condivisi.

Considera questo:

public MyFirstObject GetMeAnObject() {
    return new MyFirstObject();
}

public void MainProgram() {
    var theObject = GetMeAnObject();
    theObject.PerformOperation();
}

Che cosa accade se GetMeAOnObject viene modificato da qualcun altro per soddisfare le loro esigenze?

public MySecondObject GetMeAnObject() {
    return new MySecondObject();
}

Il metodo MainProgram avrà un grosso errore rosso su .PerformOperation (). Quello che è successo? PerformOperation ha funzionato perfettamente bene prima. Guardiamo i metodi su theObject ed è appena scomparso senza lasciare traccia. È stato lì l'ultima volta e abbiamo bisogno di quel metodo. Potresti impiegare molto tempo a inseguire la coda e cercare di capire perché, se MyFirstObject ha un metodo chiamato PerformOperation, ora non può essere visto. Tutti "sanno" che GetMeAOnObject restituisce un oggetto MyFirstObject, quindi non c'è motivo di controllarlo.

Se avessi digitato esplicitamente theObject, avresti un errore Cast non valido sulla linea che chiama GetMeAOObject, e sarebbe ovvio che GetMeAOnObject restituisca un tipo che non è quello che ti aspetti.

In breve, la dichiarazione esplicita significa che sai cosa significano gli errori. Un cast non valido significa che hai previsto un tipo e un altro tipo è stato restituito. Un membro non riconosciuto significa che il membro non è stato riconosciuto.

    
risposta data 15.08.2012 - 12:39
fonte

Leggi altre domande sui tag