Domanda

Qualcuno potrebbe consigliarmi su quale approccio da prendere durante la scrittura di costruttori C#?

In altre lingue, come C++, tutto va bene - di solito non effettuano i campi interni visibili e forniscono getter / setter per loro.

Questo significa, potresti fornire la tua classe con i costruttori, che inizializzano tutti / alcuni dei tuoi membri locali ed essere felici.


.

C#, tuttavia, ha properties, che ci consente di scrivere qualcosa di simile:

Class x = new Class { Field1 = new Field1 ...., Field2 = new Field2 }
.

Ciò consente la catena per la costruzione dell'oggetto e, come presumo, può rimuovere molti costruttori, che sarebbero necessari se non avessimo properties.

Combinando questo con valori predefiniti per le proprietà, come presumo, possiamo liberarci completamente di costruttori non specializzati, che effettivamente fanno del lavoro.

Ora - va bene rimuovere i costruttori ridondanti e consentire l'oggetto che costruisce tramite l'inizializzazione del campo?

Quali sono gli svantaggi di questo approccio? Qualcuno potrebbe dare Raccomandazioni generali sulla combinazione dell'utilizzo di campi e costruttori, alcuni rules of thumb, probabilmente?

Grazie.

È stato utile?

Soluzione

La mia regola generale è semplice: se è necessario qualcosa per costruire completamente l'oggetto, dovrebbe essere un parametro CTOR.

Un buon esempio è uno degli oggetti dell helper del flusso come lo streamreader o il binaryreader.Non possono funzionare senza un oggetto stream associato, in modo che sia specificato nel costruttore.

Altri suggerimenti

A mio parere, non c'è niente di sbagliato nell'avere ciò che il termine come costruttori ridondanti.Se ha abbastanza senso per vorresti definire un costruttore, è probabilmente perché c'è una vera necessità di farlo in quel modo.

I costruttori possono essere utilizzati per forzare il consumatore a fornire valori alla classe.

La mia regola generale è che i campi sono per i dati opzionali, mentre i costruttori possono essere utilizzati per forzare i dati richiesti.

La domanda è qualcosa di una falsa dicotomia però.C ++ si comporta allo stesso modo dei c # - "campi" (che sono in realtà le proprietà - i campi sono variabili a livello di classe) sono generalmente utilizzati come getter / setter per impostare i valori interni e la sintassi di new che consente di impostare i campi è solo una stenografiaper

Class x = new Class();
x.Field1 = new Field1();
x.Field2 = new Field2();
.

La migliore pratica è creare un oggetto in uno stato utilizzabile;Prova a limitare la dipendenza dai setter delle proprietà.

Riduce le possibilità di creare un oggetto che è incompleto e conduce a un codice meno fragile.

Il codice che hai pubblicato sta usando ciò che sono chiamati inizializzatori dell'oggetto, che sono davvero solo uno zucchero sintattico che sono stati introdotti abbastanza recentemente.L'utilizzo degli inizializzatori dell'oggetto sono solo uno stenografo per chiamare un costruttore e Impostazione delle proprietà.Dovresti continuare a utilizzare costruttori in c # nello stesso modo in cui li hai usati in altre lingue - la regola generale è che se una classe richiede un oggetto o un valore per essere inizializzato correttamente, quel parametrodovrebbe essere passato attraverso il costruttore.Se il valore non è richiesto, è ragionevole renderlo una proprietà impostabile.

In generale, evito l'uso di setter a tutti quando possibile (ci sono molti, molti casi quando non è possibile).

L'approccio della costruzione senza parametri pubblici seguita dall'inizializzazione della proprietà è popolare (richiesto?) Per l'uso in XAML, molti giocattoli WPF fanno questo.

L'unico problema che affronti è un oggetto parzialmente inizializzato, ma quindi è possibile semplicemente convalidare lo stato dell'oggetto prima di tentare di utilizzare i campi.

Personalmente, apporto i parametri dei valori critici nel costruttore, creo i costruttori di copia da una copia dell'oggetto e una gamma di parametri opzionali, e devo ancora fare qualcosa che ha bisogno di consumare da xaml.

La sintassi dell'inizializzazione dell'oggetto è solo uno zucchero sintattico.Anche in c # 1 potresti scrivere

Class c = new Class();
c.Property1 = value1;
c.Property2 = value2;
c.Property3 = value3;
....
.

C # 3 sostanzialmente accorcia la sintassi per:

Class c = new Class 
{
   Property1 = value1, 
   Property2 = value2, 
   Property3 = value3
   ....
}
.

Il punto od Il consistruttore non è semplicemente impostare i campi, il costruttore deve costruire logicamente l'oggetto, in base ai parametri, in modo che quando il costruttore ritorna, ciò che ottieni è un oggetto che è pronto per essere utilizzato. .

è ok?Bene, dipende ...

Per utilizzare le inizializzatori dell'oggetto dovrai esporre i setter pubblici a tutti i campi, potresti non volere questo.Se sei felice di esporli, allora direi andare avanti e rimuovere i costruttori.Comunque solo perché può non significa che dovrebbe .Direi che rimuovendo i costruttori dovrebbe essere qualcosa che fai se trovi che tutti i tuoi campi siano pubblicabili pubblicamente, non effettuare i campi impostabili solo per consentire di rimuovere il costruttore.

I Sospetto che ti riferisca a oggetti di dominio qui, ma nel caso dei servizi, iniettando le dipendenze del servizio attraverso un costruttore rendono il servizio più autopontale, al contrario di "annullare" le tue dipendenze.Inoltre, questo ti consente di utilizzare più facilmente i contenitori di iniezione di dipendenza.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top