2013-06-14 9 views
24

Generalnie natychmiastowy initializeobject podczas dodawania go do list ten sposób --->różnica między inicjalizacji obiektu z tych dwóch sposobów, w C#

list.add(
    new foo() {      //  <--- foo() 
     field1 = value1, 
     field2 = value2 
    } 
); 

ale po prostu próbowałem --->

list.add(
    new foo {      //  <--- foo 
     field1 = value1, 
     field2 = value2 
    } 
); 

& zadziałało !!!

w 2 sposób Jestem tylko creating an object bez użycia () na ogonie tego. , więc czy ktoś ma jakiś pomysł na temat różnicy między tymi różnymi sposobami inicjowania obiektu?

+1

Istnieje wyjaśnienie na [blogu Erica Lipperta] (http://blogs.msdn.com/b/ericlippert/archive/2010/09/20/ambiguous-optional-parentheses.aspx) – StaWho

Odpowiedz

29

, więc czy ktoś ma pojęcie o różnicy między tymi różnymi sposobami inicjowania obiektu?

Nie ma żadnej różnicy. W obu przypadkach używasz object initializer, a jeśli nie podasz żadnych argumentów konstruktora, to jest to dokładnie równoważne dostarczeniu pustej listy argumentów konstruktora. Z sekcji 7.6.10.1 w specyfikacji: C# tworzenie ekspresji

Obiekt może pominąć listę argumentów konstruktora zamykające nawiasach pod warunkiem, że zawiera inicjator lub obiekt zbierania inicjatora. Pominięcie listy argumentów konstruktora i wypełnienie nawiasów jest równoważne określeniu pustej listy argumentów.

Zauważ, że gdy po prostu wywołania konstruktora bez użycia inicjatora obiektu (szelki), które mieć określić argumenty konstruktora. Więc:

Foo foo = new Foo(); // Valid 
Foo foo = new Foo;  // Invalid 
Foo foo = new Foo() {}; // Valid 
Foo foo = new Foo {}; // Valid 

„ważna” linie są dokładnie równoważne, w tym ich wykorzystanie parametrów domyślnych - tak Foo może mieć tylko konstruktora takiego:

// You can invoke this without specifying arguments 
public Foo(int x = 0) 
{ 
} 

Patrz punkt 7.6.10 z następujących Specyfikacja C# 5, aby uzyskać więcej szczegółów.

+0

, ale co jeśli Foo nie robi nie ma żadnego konstruktora takiego jak ty, który mówi 'Foo (int x = 0)'. bcoz mój kod nadal działa bez konstruktora –

+0

@AshokDamani: Zastosowana zostanie domyślna wartość. To po prostu syntaktyczny cukier, jak gdybyś napisał pusty nawias. Z parametrem "x" będącym parametrem opcjonalnym, możesz _ wywołać 'var f = new Foo()' (który przechodzi w '0') lub' var f = new Foo() {} '(który przechodzi w' 0') lub 'var f = new Foo {}' (który przechodzi w '0') lub możesz go jawnie określić:' var f = new Foo (9999) {} 'EDIT: Tak, przepraszam za pytanie' struct', określają zawsze domyślne konstruktory; Przeoczyłem, że zadeklarowałeś "x" jako opcjonalny parametr. –

+0

@AshokDamani: Jeśli nie dostarczysz * żadnych * konstruktorów, kompilator C# dostarczy ci bez parametrów, powszechnie znany jako "domyślny konstruktor". –

6

Nie ma różnicy. W inicjatorze obiektu drugiej postaci (bez nawiasów) konstruktor bez parametrów jest używany domyślnie, ale można go jawnie określić. Jeśli chcesz przekazać parametry do konstruktora, musisz użyć pierwszego formularza (oczywiście z pewnymi wartościami).

9

Obie są inicjatorami obiektów. Nie ma różnicy. To dobre pytanie. Myślę, że za kulisami wynik jest taki sam ... Kompilator tworzy obiekt z pustym konstruktorem i ustawia właściwości.

3

Jak wyjaśniono głównie, nie ma różnicy w obu. Zawsze, gdy tworzymy obiekt, zawsze jest domyślny konstruktor utworzony bez żadnego parametru, który inicjuje członków obiektu z wartościami domyślnymi (pusty/NULL), oznacza, że ​​zostanie użyta twoja druga metoda. Ale kiedy przekazujemy parametr w czasie inicjalizacji obiektu, należy zdefiniować konstruktora dla pasującej definicji, inaczej spowoduje to błąd składni.Jeśli nie ma zdefiniowanego konstruktora dla dopasowania definicji, nie ma nic do przekazania jako wartości lub do zainicjowania elementów obiektu.

Powiązane problemy