Có sự khác nhau giữa biến loại tham chiếu không được khởi tạo hoặc có giá trị null không? Tôi đọc ở đâu đó mà không phải init có nghĩa là null nhưng ở nơi khác tôi đọc cái gì khác. Cảm ơn!Giá trị không được khởi tạo so với giá trị null của các loại tham chiếu
Trả lời
Lưu ý rằng lĩnh vực đang ngầm khởi tạo null
, vì vậy đây chỉ ảnh hưởng đến các biến. Trong tinh khiết C# bạn không thể truy vấn giá trị của trường chưa được khởi tạo (bạn cần "phân bổ xác định"), do đó, nó không phải là câu hỏi.
Bạn có thể làm điều này bằng cách lạm dụng IL mặc dù - bằng cách tuyên bố một tham số out
, và sử dụng DynamicMethod
để viết một phương pháp mà không gán nó (có giá trị trong IL, nhưng không phải trong C#). Và sau đó bạn thấy rằng bạn sẽ thấy null
s.
Điều này lần lượt là do cờ IL (.locals init
) cho biết "xóa ngăn xếp cho tôi trước khi nhập phương thức này" trên gọi mã (C#). Trình biên dịch C# luôn đặt cờ này. Nếu bạn lại lạm dụng IL để viết một phương thức không đặt cờ này, bạn có thể thấy rác. Có thể là mọi thứ. Nhưng thời điểm này, bạn xứng đáng với trường hợp ngoại lệ bạn nhận được :)
Dưới đây là một ví dụ về người đầu tiên (không phải là thứ hai, đó là phức tạp hơn):
delegate void AbuseMe(out object foo);
static void Main() {
DynamicMethod dyn = new DynamicMethod("Foo",
typeof(void), new[] { typeof(object).MakeByRefType() });
dyn.GetILGenerator().Emit(OpCodes.Ret);
AbuseMe method = (AbuseMe) dyn.CreateDelegate(typeof(AbuseMe));
object obj; // this **never** gets assigned, by **any** code
method(out obj);
Console.WriteLine(obj == null);
}
Để làm rõ, mã DynamicMethod
chỉ đơn giản là viết tương đương với mã này, không hợp pháp trong C#:
static void Foo(out object whatever) { } // note, whatever is not assigned
này hoạt động vì như xa như CLR là có liên quanout
không tồn tại - chỉ có ref
. Vì vậy, đây không phải là không hợp lệ IL - nó chỉ là ngôn ngữ (C#) mà đặt ý nghĩa để out
và yêu cầu rằng nó được gán một giá trị.
Vấn đề là Main()
vẫn có cờ .locals init
; nên đằng sau hậu trường obj
là được xóa thành null
(tốt, toàn bộ không gian ngăn xếp chỉ đơn giản là bị xóa). Nếu tôi biên soạn từ IL mà không có lá cờ đó (và có một số mã khác tại chỗ để làm cho không gian ngăn xếp bẩn) Tôi có thể nhìn thấy rác. Bạn có thể xem thêm về .locals init
trên Liran Chen's blog.
Tuy nhiên, để trả lời câu hỏi:
- cho các lĩnh vực: lĩnh vực tài liệu tham khảo kiểu uninitialized là
null
- đảm bảo bởi spec - cho các biến: bạn không thể yêu cầu, nhưng như một thực hiện chi tiết (không được phụ thuộc vào): có, nó sẽ là
null
mặc dù bạn không thể hỏi; p
"Nó phụ thuộc"
Đối với bình thường biến thành viên khi một giá trị không được xác định trong khai báo sau đó biến giả định giá trị mặc định thích hợp (null
với nhiều loại tài liệu tham khảo). Tức là, class A { string X; }
cũng giống như class A { string X = null; }
.
Đối với biến cục bộ là lỗi khi truy cập chúng trước khi giá trị có thể được chứng minh là đã được chỉ định. Mặc dù kiểu "mặc định" của chúng là null (đối với các kiểu tham chiếu), chúng không được gán ngầm định mặc định! Tức là, string F() { string x; return x; }
là lỗi biên dịch.
Hãy nhớ rằng: null
là null
:-)
- 1. C# generics: loại tham chiếu so với giá trị
- 2. Giá trị và các loại tham chiếu
- 3. Mặc định được khởi tạo so với Giá trị được khởi tạo
- 4. So sánh với giá trị NULL
- 5. So sánh một generic với null có thể là một giá trị hoặc kiểu tham chiếu?
- 6. Chuyển các loại tham chiếu theo giá trị trong C#
- 7. Trong C#, sử dụng các loại giá trị so với các loại tài liệu tham khảo
- 8. So sánh trực tiếp của C# Các loại giá trị
- 9. Lợi ích của các loại giá trị trên các loại tham chiếu?
- 10. đối tượng loại tham chiếu loại giá trị trong javascript
- 11. Xác minh giá trị tham số tham chiếu với Moq
- 12. Các loại tham chiếu không thể null
- 13. Có thể tạo chu trình tham chiếu chỉ sử dụng các loại giá trị không?
- 14. Lambda: Tại sao giá trị được ghi lại bởi giá trị const, nhưng giá trị theo từng tham chiếu không?
- 15. C# - trình bao bọc tham chiếu cho loại giá trị
- 16. Guid có được coi là loại giá trị hoặc loại tham chiếu không?
- 17. WeakHashMap và giá trị tham chiếu mạnh
- 18. Bắt buộc loại giá trị (chung) là tham chiếu
- 19. So sánh loại mẫu với giá trị số không đổi
- 20. Cách chuẩn hóa giá trị RGB với giá trị RGB tham chiếu
- 21. (mặc định) Implicit giá trị so với giá trị Explicit
- 22. Khởi tạo giá trị Scala
- 23. định vị và loại bỏ các giá trị không được tham chiếu trong strings.xml
- 24. NHibernate - bất động sản không null tham chiếu đến một giá trị null hay thoáng
- 25. Python có sao chép giá trị hoặc tham chiếu khi khởi tạo đối tượng không?
- 26. khởi mảng trực tiếp với một giá trị không đổi
- 27. Phương pháp chung có thể xử lý cả hai loại Giá trị tham chiếu và Giá trị không hợp lệ?
- 28. Chỉ định giá trị mặc định cho loại tham chiếu
- 29. Các loại giá trị có được thu gom rác không?
- 30. if (giá trị == null) vs nếu (null == giá trị)
Ok, đó là khá freaky sh! T! :) – leppie
@leppie Tôi muốn làm hài lòng, p –
Jeffrey Richter trong cuốn sách "CLR Via C#, 3rd edition" đề cập đến các biến luôn được CLR khởi tạo thành 'null'. Ông cũng nói rằng thực sự nó không cần thiết cho trình biên dịch C# để cấm sử dụng các biến không khởi tạo, nhưng trình biên dịch vẫn có hạn chế này. –