2009-06-04 43 views
12

Có sự khác biệt về việc liệu tôi khởi tạo một biến số nguyên như:C# Biến Khởi Câu hỏi

int i = 0; 
int i; 

Liệu trình biên dịch hoặc CLR điều trị này như điều tương tự? IIRC, tôi nghĩ rằng cả hai đều được coi là giống nhau, nhưng tôi dường như không thể tìm thấy bài báo.

+11

_Fields_ luôn được tự động khởi tạo thành giá trị mặc định của loại trường, trong trường hợp int là zero. Các lĩnh vực được coi là chắc chắn được giao; bạn có thể đọc nội dung của họ ngay cả trước khi phân công rõ ràng. _Locals_ không được coi là chắc chắn được giao; bạn được yêu cầu làm điều gì đó gán giá trị của một địa phương trước khi nội dung của nó được đọc. Xem phần "phân định xác định" của đặc tả C# để biết chi tiết. –

Trả lời

6

Tôi đã xem IL (sử dụng ildasm) và đúng là chỉ có bộ int trong 0 được thiết lập là 0 trong hàm tạo.

public class Class1 
{ 
    int setToZero = 0; 
    int notSet; 
} 

Tạo:

.method public hidebysig specialname rtspecialname 
     instance void .ctor() cil managed 
{ 
    // Code size  15 (0xf) 
    .maxstack 8 
    IL_0000: ldarg.0 
    IL_0001: ldc.i4.0 
    IL_0002: stfld  int32 ClassLibrary1.Class1::setToZero 
    IL_0007: ldarg.0 
    IL_0008: call  instance void [mscorlib]System.Object::.ctor() 
    IL_000d: nop 
    IL_000e: ret 
} // end of method Class1::.ctor 
+0

Nhưng không phải là nó có thể là ctor cho lớp đó xử lý khởi tạo biến cho những biến không được chỉ định rõ ràng? –

+8

Michael: các trường được khởi tạo thành giá trị mặc định (không) bởi _memory manager_, chứ không phải bởi _constructor_. –

+0

Rất cám ơn Eric Lippert vì đã làm rõ. Tôi ước gì tôi có thể cho tín dụng cho một hoặc nhiều cá nhân tham gia vào cuộc thảo luận này. Như thường lệ, tôi luôn đi bộ với nhiều kiến ​​thức hơn mà tôi đã đến đây cùng;) – coson

4

Có, nó khá nhiều là điều tương tự.

Bạn có thể tham khảo bài viết này trên Coding Horror

+0

+1 cho liên kết. Thảo luận thú vị về chủ đề này. – CAbbott

14

Nếu biến i là một biến Ví dụ, nó sẽ được gán giá trị 0 tự động. Nếu nó là một biến cục bộ trong một phương thức, nó là không xác định, vì vậy bạn sẽ cần gán nó một giá trị trước khi sử dụng nó.

Ví dụ:

class Program 
{ 
    static void Main(string[] args) 
    { 
     intTest it; 

     it = new intTest(); 

     Console.ReadLine(); 
    } 

    class intTest 
    { 
     int i; 

     public intTest() 
     { 
      int i2; 

      Console.WriteLine("i = " + i); 
      Console.WriteLine("i2 = " + i2); 
     } 
    } 
} 

trên sẽ không biên dịch vì i2 là unassigned. Tuy nhiên, bằng cách gán từ 0 đến i2, tức là

int i2 = 0; 

và biên soạn, sau đó chạy, sẽ cho thấy rằng cả hai đang giao 0.

+0

int là một cấu trúc không phải là một lớp. structs có giá trị mặc định trong khi các lớp là nul theo mặc định. –

+0

@Matthew Whited, anh không có nghĩa đó là một lớp học. Anh ấy đã nói ở lớp "cấp độ", điều đó thực sự có nghĩa là biến thể hiện. Tôi đã chỉnh sửa nó để làm rõ. – mmcdole

0

Bất cứ lúc nào bạn tạo một kiểu trong C#, nó sẽ tự động được điền vào với số 0 đệm. Trong trường hợp của một lớp (kiểu tham chiếu), điều này tương đương với một con trỏ null. Vì vậy, về mặt kỹ thuật, bất cứ lúc nào bạn đang làm việc với các lớp, sau đây là giống hệt nhau:

MyClass class; 
MyClass class2 = null; 

Với kiểu giá trị (bất kỳ cấu trúc, bao gồm int/float/đôi/etc), loại được thông qua với số không, vì vậy các nội dung sau tương đương:

int i; 
int j = 0; 

Tuy nhiên, trong một phương pháp, trình biên dịch sẽ kiểm tra xem bạn đã gán giá trị cho loại trước khi sử dụng hay chưa. Nếu bạn làm như sau, trình biên dịch sẽ phàn nàn:

int i; 
Console.WriteLine{"{0}",i); 

Về mặt kỹ thuật, ở trên nên được tốt - nhưng vì nó là một nguồn phổ biến của lỗi lập trình, trình biên dịch kiểm tra đặc biệt cho các biến cục bộ unassigned, và phàn nàn. Tuy nhiên, đây là khiếu nại biên dịch và không phải là vấn đề CLR. Bạn có thể làm cho IL làm điều đó ở trên, và nó chạy tốt.

0

Đây chỉ là tương đương cho các lĩnh vực (các biến lớp). Các trường được gán tự động các giá trị mặc định khi lớp được khởi tạo. Trong một phương thức hoặc thuộc tính, biến chưa được gán vẫn chưa được gán và sẽ gây ra lỗi trình biên dịch nếu bạn cố truy cập vào giá trị của nó.

1

Với tất cả bài nói chuyện này, điều đáng nói đến là từ khóa "mặc định" trong C#.

I.e. int i; tương đương với int i = default(int); tương đương với int i = 0;MyClass o = default(MyClass); tương đương với MyClass o = null;

Điều này đặc biệt phù hợp khi sử dụng phương pháp LINQ như .SingleOrDefault() bởi vì bạn luôn có thể sử dụng sau đây để làm cho mã của bạn dễ đọc hơn:

int someValue = collection.<various linq methods>.SingleOrDefault(); 
if (someValue == default(int)) 
{ 
    //Code for the default case 
} 

phản ứng
MyClass someValue = collection.<various linq methods>.SingleOrDefault(); 
if (someValue == default(MyClass)) 
{ 
    //Code for the default case 
} 
0

khác nhau ở đây là loại sai lầm, kể cả thứ e tham chiếu bài viết trong trang web "Mã hóa Kinh dị".

Trình biên dịch sẽ tối ưu hóa mã của bạn để xóa tất cả các khởi tạo "không cần thiết" khi được định cấu hình để tối ưu hóa mã được tạo. Xin lưu ý rằng đây là hành vi mặc định khi biên dịch trong chế độ "Phát hành".

Tôi, cho một, nghĩ rằng luôn luôn rất hữu ích để khởi tạo tất cả các biến của bạn. Hiệu suất hit sẽ ở mức tối thiểu trong chế độ gỡ lỗi và không ở chế độ phát hành, nhưng lợi ích của việc đặt rõ ràng các biến sẽ rất lớn đối với bất kỳ ai duy trì mã trong tương lai, trong kiểu "mã tài liệu với mã" tốt hơn. Tôi nhớ đồng nghiệp rất giàu kinh nghiệm của tôi nghĩ rằng giá trị mặc định của Int32 là Int32.MinValue thay vì 0. Những loại nhầm lẫn này luôn xảy ra với những thứ liên quan đến mã và, đối với tôi, chúng nên tránh trong hầu hết các trường hợp.