2009-04-20 5 views
6

Có quy tắc nào cần làm theo khi sử dụng từ khóa new và khi nào không khi khai báo đối tượng?Để "mới" hoặc không "mới"

List<MyCustomClass> listCustClass = GetList(); 

HOẶC

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

Bạn có thực sự hỏi bạn có nên viết nhà máy hay không? – annakata

+6

Không, tôi nghĩ anh ta không hiểu rằng "mới" có nghĩa là một cuộc gọi của nhà xây dựng và tạo ra một vật thể mới. Nếu không, anh ta sẽ biết rõ hơn là tạo ra một vật thể mới và sau đó vứt nó đi. Có lẽ anh ta đến từ VB.NET, nơi mà từ khóa "Mới" có thể là một phần của cú pháp khai báo, vì vậy anh ta nghĩ đó là những gì trong C#. –

+0

Tôi không chắc chắn về các thẻ C# và .NET trên thẻ này vì nó là một câu hỏi OOP khá chung chung. – Welbog

Trả lời

8

Trong trường hợp của bạn, có vẻ như việc tạo đối tượng thực tế của đối tượng đang được thực hiện bên trong phương thức GetList() của bạn. Vì vậy, mẫu đầu tiên của bạn sẽ được sử dụng đúng.

Khi được tạo, List<MyCustomClass> của bạn được lưu trữ trong heap và listCustClass của bạn chỉ đơn giản là tham chiếu đến đối tượng mới đó. Khi bạn đặt listCustClass thành GetList() con trỏ tham chiếu của listCustClass bị hủy và được thay thế bằng một con trỏ tham chiếu đến bất kỳ số nào trả về GetList() (có thể là null). Khi điều này xảy ra ban đầu của bạn List<MyCustomClass> vẫn còn trong đống, nhưng không có đối tượng trỏ đến nó, do đó, nó chỉ lãng phí nguồn lực cho đến khi Garbage Collector đến xung quanh và làm sạch nó lên.

Để tổng hợp nó mỗi khi bạn tạo một đối tượng mới, sau đó từ bỏ nó, như ví dụ thứ hai, về cơ bản bạn đang lãng phí bộ nhớ bằng cách điền vào đống thông tin vô ích.

18

Chỉ ví dụ đầu tiên của bạn làm cho bất kỳ ý nghĩa trong trường hợp này vì trong trường hợp thứ hai bạn sẽ ngay lập tức thay thế các danh sách được tạo ra với một trả về bởi phương pháp này. Việc khởi tạo một danh sách thành một danh sách trống mới có ý nghĩa trong các trường hợp bạn đang thêm vào danh sách đó hoặc khi có thể phương thức bạn đang gọi để điền danh sách bằng cách nào đó có thể dẫn đến giá trị rỗng khi bạn mong đợi một danh sách trống .

Ví dụ nơi tôi có thể sử dụng khởi tạo vào danh sách trống mới.

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

hoặc

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

Trong trường hợp thứ hai của bạn, bạn đang tạo ra một đối tượng mới trên dòng đầu tiên chỉ để vứt nó đi trên dòng thứ hai. Hoàn toàn không cần thiết.

+1

Tôi không thể tin rằng đây là câu trả lời được trả lời nhiều nhất của tôi. – erikkallen

2

Nếu bạn có thể nội tuyến nó mà không mất đi ý nghĩa và sự rõ ràng về những gì bạn đang hoàn thành, bằng mọi cách, nội tuyến.

Chỉnh sửa: Và, như tôi thường xuyên nội tuyến, tôi thậm chí không nghĩ về tham chiếu đối tượng mồ côi. Doh. =)

+0

Thật tuyệt khi biết * những gì * downvote là dành cho. =) –

+0

Đó là câu trả lời của Daniel - chỉ cần gõ sai mục ...: D –

+0

Ahaha. Đồng nghiệp của tôi cũng bị mất tích với con chuột cả ngày. Phải là thứ hai. =) –

3

Bạn sử dụng từ khóa new để tạo phiên bản mới của đối tượng. Nó không rõ ràng từ câu hỏi của bạn, phương thức GetList có thể là gì, nhưng có lẽ là tạo danh sách mới (do đó di chuyển từ khóa new ở một nơi khác) hoặc trả lại danh sách hiện có (trong đó ai đó được tạo tại một điểm sử dụng new).

+0

Các GetList nên được sử dụng mới để tạo ra một danh sách để nó có thể trả lại cho người gọi. đúng? Có cách nào khác để triển khai GetList không? –

+0

Vấn đề là ai đó đang tạo danh sách, cho dù đó là GetList hay một số phương thức mà các cuộc gọi GetList. –

0

Đừng nghĩ về điều đó về "tôi nên sử dụng mới khi tôi khai báo".

Bạn sử dụng mới khi bạn đang chỉ định (có thể là một phần của tuyên bố).

Ví dụ đầu tiên là chính xác, ví dụ thứ hai là một sự lãng phí không cần thiết của tài nguyên thời gian chạy.

1

Không có quy tắc chung nào, nhưng thông thường bạn có thể áp dụng hầu hết thời gian.

Một đối tượng cần được khởi tạo khi nó được tạo. Hàm GetList() của bạn trả về một cách rõ ràng một IList (được tạo ra) do đó đoạn mã thứ hai là khá không cần thiết (Bạn khởi tạo một IList và loại bỏ nó một cách hiệu quả trên dòng tiếp theo).

Đoạn đầu tiên hoàn toàn thích hợp, tuy nhiên.

0

Trong C#, tất cả các phiên bản của lớp phải được tạo bằng từ khóa new. Nếu bạn không sử dụng new trong ngữ cảnh hiện tại của mình, bạn có tham chiếu null hoặc bạn đang gọi một hàm sử dụng new để instanciate lớp.

Trong trường hợp này, có vẻ như GetList() sử dụng new để tạo danh sách mới.

3

Từ khóa mới về cơ bản được sử dụng để phân bổ không gian trên heap. Nếu bạn đang tạo kiểu giá trị (cấu trúc, v.v ...), bạn không phải sử dụng từ khóa mới. Tuy nhiên, các biến tham chiếu phải được new'd trước khi chúng được sử dụng.

Trong ví dụ trên, có vẻ như GetList() trả về tham chiếu thuộc loại danh sách đã được tạo (new'd) ở đâu đó trong hàm. Do đó trong kịch bản này, new'ing là vô nghĩa.