Qual è la differenza tra un inizializzatore di oggetti e un costruttore?

Quali sono le differenze tra i due e quando useresti un “inizializzatore di oggetti” su un “costruttore” e viceversa? Sto lavorando con C #, se questo è importante. Inoltre, il metodo di inizializzazione dell’object è specifico per C # o .NET?

Gli inizializzatori di oggetti sono stati aggiunti al C # 3, per semplificare la costruzione di oggetti quando si utilizza un object.

I costruttori vengono eseguiti con 0 o più parametri e vengono utilizzati per creare e inizializzare un object prima che il metodo chiamante ottenga l’handle dell’object creato. Per esempio:

MyObject myObjectInstance = new MyObject(param1, param2); 

In questo caso, il costruttore di MyObject verrà eseguito con i valori param1 e param2 . Questi sono entrambi utilizzati per creare il nuovo MyObject in memoria. L’object creato (che viene configurato utilizzando tali parametri) viene restituito e impostato su myObjectInstance .

In generale, è buona norma avere un costruttore che richiede i parametri necessari per configurare completamente un object, in modo che sia imansible creare un object in uno stato non valido.

Tuttavia, ci sono spesso proprietà “extra” che possono essere impostate, ma non sono richieste. Questo potrebbe essere gestito attraverso costruttori sovraccarichi, ma porta ad avere molti costruttori che non sono necessariamente utili nella maggior parte delle circostanze.

Questo porta agli inizializzatori di oggetti: un inizializzatore di oggetti ti consente di impostare proprietà o campi sul tuo object dopo che è stato costruito, ma prima che tu possa usarlo con qualsiasi altra cosa. Per esempio:

 MyObject myObjectInstance = new MyObject(param1, param2) { MyProperty = someUsefulValue }; 

Questo si comporterà come se si facesse questo:

 MyObject myObjectInstance = new MyObject(param1, param2); myObjectInstance.MyProperty = someUsefulValue; 

Tuttavia, negli ambienti a più thread l’atomicità dell’object inizializzatore può essere utile, poiché impedisce all’object di essere in uno stato non completamente inizializzato (si veda questa risposta per maggiori dettagli) – è nullo o inizializzato come si intendeva.

Inoltre, gli inizializzatori degli oggetti sono più semplici da leggere (specialmente quando si impostano più valori), quindi offrono lo stesso vantaggio di molti sovraccarichi sul costruttore, senza la necessità di sovraccaricare molti l’API per quella class.

Un costruttore è un metodo definito su un tipo che accetta un numero specificato di parametri e viene utilizzato per creare e inizializzare un object.

Un inizializzatore di oggetti è un codice che viene eseguito su un object dopo un costruttore e può essere utilizzato per impostare in modo succinto qualsiasi numero di campi sull’object su valori specificati. L’impostazione di questi campi si verifica dopo la chiamata del costruttore.

Si utilizzerà un costruttore senza l’aiuto di un inizializzatore di oggetti se il costruttore imposta sufficientemente lo stato iniziale dell’object. Tuttavia, un inizializzatore di oggetti deve essere utilizzato insieme a un costruttore. La syntax richiede l’uso esplicito o implicito (VB.Net e C #) di un costruttore per creare l’object iniziale. Si utilizzerà un inizializzatore di oggetti quando il costruttore non inizializza sufficientemente l’object al proprio utilizzo e alcuni semplici campi e / o set di proprietà lo farebbero.

Quando lo fai

 Person p = new Person { Name = "a", Age = 23 }; 

questo è ciò che un inizializzatore di oggetti essenzialmente fa:

 Person tmp = new Person(); //creates temp object calling default constructor tmp.Name = "a"; tmp.Age = 23; p = tmp; 

Ora questo facilita un comportamento come questo . Sapere come funzionano gli inizializzatori degli oggetti è importante.

Se hai delle proprietà che DEVONO essere impostate sul tuo object affinché funzioni correttamente, un modo è quello di esporre solo un singolo costruttore che richiede le proprietà obbligatorie come parametri.

In tal caso, non puoi creare il tuo object senza specificare quelle proprietà obbligatorie. Qualcosa di simile non può essere applicato dagli inizializzatori di oggetti.

Gli inizializzatori di oggetti sono in realtà solo una “comodità di syntax” per abbreviare i compiti iniziali. Bello, ma non molto rilevante dal punto di vista funzionale.

Marc

Un costruttore è un metodo (possibilmente) che accetta parametri e restituisce una nuova istanza di una class. Può contenere logica di inizializzazione. Qui sotto puoi vedere un esempio di costruttore.

 public class Foo { private SomeClass s; public Foo(string s) { s = new SomeClass(s); } } 

Considerare ora il seguente esempio:

 public class Foo { public SomeClass s { get; set; } public Foo() {} } 

È ansible ottenere lo stesso risultato del primo esempio utilizzando un inizializzatore di oggetti, assumendo che sia ansible accedere a SomeClass, con il seguente codice:

 new Foo() { s = new SomeClass(someString) } 

Come si può vedere, un inizializzatore di oggetti consente di specificare i valori per i campi pubblici e le proprietà pubbliche (impostabili) nello stesso momento in cui viene eseguita la costruzione, ed è particolarmente utile quando il costruttore non fornisce alcun sovraccarico inizializzando determinati campi. Per favore, però, gli inizializzatori degli oggetti sono solo zucchero sintattico e che dopo la compilazione non differiscono in realtà da una sequenza di compiti.