Perché i generatori di codice utilizzano sempre identificatori pienamente qualificati?

6

Quando guardi il codice di Winforms Designer, vedi cose come questa:

this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", ... etc.

invece di

using System.Drawing;
label1.Font = new Font("Microsoft Sans Serif", ... etc.

Lo stesso vale per strumenti come Linq to XSD , XSD2Code e, sospetto, di Linq to SQL. Questi strumenti generano cumuli di codice con nomi estremamente lunghi e completi.

Non sarebbe più semplice generare le appropriate dichiarazioni using e abbandonare i nomi lunghi? O c'è qualche motivo tecnico per questo che mi manca?

Nota: per coloro che sono sconcertati dall'idea che potrei voler che queste classi siano effettivamente leggibili da un umano, nota che questo è esattamente il mio obiettivo. Ho una XSD con circa 300 classi, non voglio scriverle tutte a mano, e sì, mi piacerebbe che sembrassero un normale codice scritto da umani.

    
posta Robert Harvey 13.02.2013 - 00:54
fonte

4 risposte

20

I generatori di codice dichiarano esplicitamente le classi che stanno utilizzando per prevenire comportamenti imprevisti dai conflitti di denominazione.

Se un progetto include una classe con lo stesso nome di una classe in un altro spazio dei nomi, introduce un'ambiguità. Dove c'è ambiguità, il compilatore ha come valore predefinito lo spazio dei nomi locale. Considera questo:

using System.Drawing;

namespace MyProject {
    class MyClass {
        void InitialiseComponent() {
            this.label1.Font = new Font("Microsoft Sans Serif", ...);
        }
    }
}

Funziona bene così com'è. Ma cosa succede se aggiungiamo una nuova classe Font al progetto?

namespace MyProject {
    class Font : System.Drawing.Font {
        public Font(string fontName, ...) { ... }
    }
}

Ora abbiamo System.Drawing.Font e MyProject.Font . Il codice in MyProject.MyClass.InitialiseComponent() è ancora compilato ed eseguito. Ma quale versione di Font usa?

Il compilatore ha come valore predefinito lo spazio dei nomi locale di MyProject.MyClass e utilizza MyProject.Font , anche se è definito using System.Drawing .

È questo che voleva il programmatore? Non è compito dell'IDE di indovinare. Il programmatore dovrebbe dichiarare esplicitamente se vuole utilizzare la loro implementazione di Font o System.Drawing.Font .

All'interno di un singolo progetto, l'IDE potrebbe rilevare questo cambiamento e alterare tutti i file generati dal codice per chiarire quale Font usare. Ma cosa succede se il progetto non è attualmente caricato? In che modo l'IDE può sapere quali file richiedono una manutenzione futura? Inizia per essere specifico e non c'è mai ambiguità.

    
risposta data 13.02.2013 - 02:01
fonte
9

Generatori di codice sono generalmente progettati per creare codice leggibile dalla macchina più del codice leggibile dall'uomo. Ci si aspetta che gli umani lavorino principalmente con il formato originale usato come input per il generatore. Le dichiarazioni using migliorano la leggibilità umana, ma ai computer non interessa.

Prova a seguire l'esercizio di scrivere un semplice generatore di codice come descrivi, e vedrai perché utilizzano i nomi completi. Di solito si crea una sorta di albero di sintassi astratto in base al formato di input originale, quindi si cammina l'albero per generare il codice. L'utilizzo delle istruzioni using richiederebbe la conservazione di un ulteriore "registro" di istruzioni using che si desidera utilizzare, controllandone i duplicati, quindi tornando a inserirli nella parte superiore del file. Ne vale la pena se è necessario, come dire una dichiarazione include , ma è molto più difficile di quanto valga la pena per qualcosa con una soluzione abbastanza facile.

    
risposta data 13.02.2013 - 01:14
fonte
2

Se hai creato o importato un'altra libreria che ha anche definito Font, quindi senza una qualifica completa il codice generato avrebbe un errore.

    
risposta data 13.02.2013 - 00:58
fonte
2

I nomi brevi e using s sono utili per codice scritto umanamente, perché:

  • gli sviluppatori preferiscono scrivere var defaultFont = new Font(...) contro var defaultFont = new System.Drawing.Font(...) ,

  • altri sviluppatori preferiscono il codice leggibile, non qualcosa con nomi di variabili lunghe e tipi completi.

Ecco perché using s è stata inventata in un primo momento. Potremmo specificare tipi completamente qualificati, ma ridurrebbe drasticamente la qualifica del codice.

Non sarebbe più facile abbandonare i nomi lunghi nel codice generato? Non proprio; in effetti, non importa. Quando il codice genera altro codice, non fa alcuna differenza tra type.Name e type.FullName . Usando i nomi completi, il generatore di codice non ha bisogno di anteporre il using s, rendendo più facile lo sviluppo del generatore.

Ho notato che hai commentato la risposta di Karl Bielefeldt, scrivendo:

That's great if you can treat the generated code as a black box, and never have to modify it. That's not always the case.

I generatori di codice non sono mai progettati per generare codice pulito che dovrebbe essere letto e modificato dall'uomo. In generale, non dovresti modificare il codice generato, perché o perdi la possibilità di usare di nuovo il generatore, o tutte le tue modifiche andranno perse la prossima volta che chiami il generatore. I casi in cui è necessario modificare manualmente il codice generato sono rari ed è comprensibile che le persone che scrivono generatori di codice non tengano conto di tali scenari.

Se i generatori di codice fossero scritti per gli umani, avrebbero generato il codice:

  • con alcuni altri commenti,

  • Correttamente rientrato,

  • Conforme alle linee guida di stile (vedi te stesso quanti avvisi StyleCop sono causati dal codice generato per una semplice classe Windows Forms),

  • Con nomi chiari che non iniziano con @ carattere ,

  • Unità sottoposta a test di regressione.

Questo renderebbe il codice molto più leggibile, ma introdurrebbe anche potenziali bug e altro codice da scrivere in supporto durante lo sviluppo di un generatore di codice.

    
risposta data 13.02.2013 - 01:15
fonte

Leggi altre domande sui tag