2015-08-25 12 views
11

Trích dẫn MSDN - const (C# reference):Tại sao một Loại không thể được sử dụng làm giá trị không đổi?

Một biểu thức hằng số là một biểu hiện có thể được đánh giá đầy đủ tại thời gian biên dịch. Do đó, các giá trị có thể duy nhất cho các tham số của các loại tham chiếu là chuỗi và tham chiếu null.

Theo: typeof(T) vs. Object.GetType() performance, typeof(T) là biểu thức thời gian biên dịch.

Vậy tại sao không thể Type là giá trị không đổi?

Các mã sau sẽ không biên dịch:

public const Type INT_TYPE = typeof(int); 
+0

Tôi tự hỏi điều gì làm cho bạn đặt câu hỏi này, chắc chắn bạn sẽ không sử dụng hằng số như vậy trong mã thực? – MarioDS

+0

Thay vào đó, tôi sử dụng chỉ đọc tĩnh. –

Trả lời

5

Hằng số được thay thế bằng trình biên dịch với các giá trị theo chữ trong mã IL kết quả. Nhưng typeof là một lời gọi phương thức:

typeof(int); 

// Becomes: 
L_0000: ldtoken int32 
L_0005: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) 
0
public const Type INT_TYPE = typeof(int); 

Lý do mã trên sẽ không biên dịch là chính xác lý do đã nêu bởi MSDN- giá trị của hằng số không thể được xác định vào thời điểm đó ứng dụng được biên dịch. Sử dụng typeof (int) yêu cầu xác định giá trị cho hằng số tại thời gian chạy . Theo lý thuyết, .NET có thể cho phép tuyên bố ở trên để biên dịch, nhưng sau đó nó sẽ không phải là một hằng số theo nghĩa nghiêm ngặt của từ đó.

2

Từ MSDN:

Constants có thể con số, giá trị Boolean, chuỗi, hoặc một tham chiếu null.

Constants về cơ bản giới hạn giá trị nguyên thủy có thể được biểu diễn dưới dạng một giá trị nhị phân lúc biên dịch-type (kể từ khi nó được "tiêm" vào mã khách hàng khi nó được biên soạn). Vì Type là một lớp có nhiều thuộc tính, không có biểu diễn nhị phân đơn giản có thể được "nhúng vào" mã khách hàng.

1

Trình biên dịch C# và IL chắc chắn hỗ trợ các loại dưới dạng biểu thức không đổi, ít nhất là trong các tình huống nhất định. Nhìn vào các thuộc tính, họ sử dụng này rất nhiều:

[DebuggerTypeProxy(typeof(Mscorlib_CollectionDebugView<>))] 

Các loại được nhúng vào như là một chuỗi trong trình biên dịch tạo ra mã, trên đường biên dịch mã IL sau:

.custom instance void System.Diagnostics.DebuggerTypeProxyAttribute::.ctor(class System.Type) = (
    01 00 39 53 79 73 74 65 6d 2e 43 6f 6c 6c 65 63 
    74 69 6f 6e 73 2e 47 65 6e 65 72 69 63 2e 4d 73 
    63 6f 72 6c 69 62 5f 43 6f 6c 6c 65 63 74 69 6f 
    6e 44 65 62 75 67 56 69 65 77 60 31 00 00 
) 

Nếu bạn kiểm tra việc dữ liệu nhị phân, bạn sẽ nhận thấy đây là tên lớp hoàn toàn đủ điều kiện mà không có bất kỳ nhận dạng lắp ráp nào (System.Collections.Generic.Mscorlib_CollectionDebugView`1).

Để trả lời câu hỏi của bạn: Tôi không thấy bất kỳ lý do kỹ thuật nào tại sao điều này không thể thực hiện được, cũng như tôi không thể tưởng tượng khả năng tương thích. mà không ảnh hưởng đến kiểu được biên dịch trước đó, tham chiếu đến nó.

Các vấn đề liên quan