2009-04-20 4 views
6

Czy istnieje pewna reguła do naśladowania, kiedy należy użyć słowa kluczowego new, a kiedy nie do zadeklarowania obiektów?Do "nowego" lub nie do "nowego"

List<MyCustomClass> listCustClass = GetList(); 

LUB

List<MyCustomClass> listCustClass = new List<MyCustomClass>(); 
listCustClass = GetList(); 
+0

Czy naprawdę pytasz, czy powinieneś pisać fabryki, czy nie? – annakata

+6

Nie, myślę, że nie rozumie, że "nowy" oznacza wywołanie konstruktora i utworzenie nowego obiektu. W przeciwnym razie wiedziałby, że lepiej jest stworzyć nowy obiekt, a potem go wyrzucić. Być może pochodzi on z VB.NET, gdzie słowo kluczowe "New" może być częścią składni deklaracji, więc uważa, że ​​tak właśnie jest w języku C#. –

+0

Nie jestem pewien co do znaczników C# i .NET na tym, ponieważ jest to dość ogólne pytanie OOP. – Welbog

Odpowiedz

8

W scenariuszu wydaje się, że rzeczywiste tworzenie obiektu odbywa się wewnątrz metody GetList(). Tak więc twoja pierwsza próbka byłaby poprawnym użyciem.

Po utworzeniu Twój List<MyCustomClass> jest przechowywany w stercie, a twój listCustClass jest po prostu odniesieniem do tego nowego obiektu. Po ustawieniu parametru listCustClass na GetList() wskaźnik referencyjny listCustClass jest odrzucany i zastępowany wskaźnikiem odniesienia dla zwracanej wartości GetList() (może być pusta). Kiedy tak się dzieje, oryginalny plik List<MyCustomClass> nadal znajduje się w stercie, ale żadne obiekty go nie wskazują, więc marnuje zasoby, dopóki nie pojawi się Garbage Collector i nie wyczyści go.

Podsumowując za każdym razem, gdy tworzysz nowy obiekt, porzuć go, tak jak w drugim przykładzie, marnujesz pamięć, wypełniając stertę niepotrzebnymi informacjami.

18

Tylko Twój pierwszy przykład ma jakiś sens w tym przypadku, ponieważ w drugim przypadku są natychmiast zastępując utworzonej listy z jednej zwracanej przez metodę. Inicjowanie listy do nowej pustej listy ma sens w przypadkach, gdy dodajesz ją do listy lub gdy jest możliwe, że metoda, którą wywołujesz w celu zapełnienia listy, może w jakiś sposób spowodować wartość pustą, gdy w przeciwnym razie oczekiwałbyś pustej listy .

Przykłady, w których mógłbym użyć inicjalizacji do nowej, pustej listy.

List<MyCustomClass> listCustClass = new List<MyCustomClass>(); 
listCustClass.AddRange(GetList()); 

lub

List<MyCustomClass> listCustClass = new List<MyCustomClass>(); 
try 
{ 
    listCustClass = GetList(); 
} 
catch (SqlException) 
{ 
} 
return listCustClass; 
43

W swoim drugim przypadku użytkownik tworzy nowy obiekt na pierwszej linii po prostu wyrzucić na drugiej linii. Całkowicie niepotrzebne.

+1

Nie mogę uwierzyć, że jest to moja zdecydowanie najbardziej przecząca odpowiedź. – erikkallen

2

Jeśli możesz wbudować go bez utraty znaczenia i jasności tego, co robisz, za wszelką cenę, w linii.

Edycja: I, jak regularnie wstawiam, nie myślałem nawet o osieroconym referencji obiektu. Doh. =)

+0

Byłoby miło wiedzieć, * o co * chodziło. =) –

+0

To była odpowiedź Daniela - po prostu trafiłeś w niewłaściwy wpis ...: D –

+0

Ahaha. Mój kolega cały dzień też nie zauważył swojej myszy. Musi być poniedziałek. =) –

3

Używasz słowa kluczowego new do skonstruowania nowej instancji obiektu. Z twojego pytania nie wynika, co to jest metoda GetList, ale prawdopodobnie tworzy ona nową listę (przenosząc w ten sposób słowo new gdzie indziej) lub zwraca istniejącą listę (która ktoś utworzona w jednym punkcie przy użyciu new).

+0

Lista GetList powinna używać nowego do utworzenia listy, aby mogła zwrócić ją do osoby dzwoniącej. dobrze? Czy istnieje inny sposób implementacji GetList? –

+0

Chodzi o to, że ktoś tworzy listę, niezależnie od tego, czy jest to GetList, czy jakaś metoda wywoływana przez GetList. –

0

Nie myśl o tym w kategoriach "powinienem użyć nowego, gdy deklaruję".

Używasz nowego, gdy przypisujesz (które może być częścią deklaracji).

Pierwszy przykład jest poprawny, drugi to niepotrzebne marnowanie zasobów środowiska wykonawczego.

1

Nie ma pewnej zasady, ale istnieje zdrowy rozsądek, który można zastosować przez większość czasu.

Obiekt musi być tworzony w instancji podczas tworzenia. Twoja funkcja GetList() pozornie zwraca (utworzoną) IList, dlatego drugi fragment kodu jest dość niepotrzebny (Tworzysz IList i skutecznie odrzucasz go w następnej linii).

Pierwszy fragment jest jednak całkowicie odpowiedni.

0

W języku C# wszystkie wystąpienia klas muszą zostać utworzone za pomocą słowa kluczowego new. Jeśli nie używasz new w bieżącym kontekście, masz albo odwołanie zerowe, albo wywołujesz funkcję, która używa new do inicjowania klasy.

W tym przypadku wygląda na to, że GetList() używa new do utworzenia nowej listy.

3

Nowe słowo kluczowe służy zasadniczo do przydzielania miejsca na stercie. Jeśli tworzysz typ wartości (structs, etc ...), nie musisz używać nowego słowa kluczowego. Jednak zmienne referencyjne muszą zostać zmienione zanim zostaną użyte.

W powyższym przykładzie wygląda na to, że GetList() zwraca referencję, która jest typu List, która zostałaby utworzona (newd) gdzieś w obrębie funkcji. Dlatego w tym scenariuszu new'ing nie ma sensu.