2012-01-20 24 views

Trả lời

5

Từ MSDN - Named and Optional Parameters:

A default value must be one of the following types of expressions:

  • a constant expression;

  • an expression of the form new ValType(), where ValType is a value type, such as an enum or a struct;

  • an expression of the form default(ValType), where ValType is a value type.


typeof không nhất thiết phải trở về một thời gian biên dịch thường xuyên vì nó có thể đưa ra kết quả khác nhau tùy thuộc vào ngữ cảnh.

+0

Loại trôi qua cho 'typeof' phải được giải quyết tại thời gian biên dịch. Do đó tôi không thể hiểu ý bạn là gì. Nếu những gì bạn nói là đúng, thuộc tính cũng sẽ không cho phép 'loại hằng số'. – leppie

+0

leppie, ý bạn là gì bởi "thuộc tính cũng nên không cho phép 'loại hằng số'"? Các thuộc tính giới hạn các giá trị là các hằng số ở đâu? –

+1

@Fujiy - Các tham số được truyền vào các hàm tạo thuộc tính cần phải là các hằng số thời gian biên dịch. – Oded

4

bởi vì nó không nhất thiết phải là một biểu thức liên tục. ví dụ của bạn có một typeof trên một lớp đơn giản nhưng nếu lớp đó là chung chung thì sao? rõ ràng đây không phải là hằng bởi cho đến nay:

class MyClass<T> 
{ 
    public void MyMethod(Type targetType = typeof(MyClass<T>)) 
    { 
    } 
} 
11

Tôi không phải là một chuyên gia IL, nhưng dường như nó gọi một phương pháp tại L_0005:

return typeof(int); 

Nó rất giống nhau của:

.maxstack 1 
.locals init (
    [0] class [mscorlib]System.Type typeofvar) 
L_0000: ldtoken int32 
L_0005: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) 
L_000a: stloc.0 
L_000b: ldloc.0 
L_000c: ret 

Bạn có thể thấy rằng nó không phải là một hằng số kiểu viết mã:

const Type constType = typeof(int); 

Đó trả về một lỗi:

Constant initialize must be compile-time constant 
+2

+1 cách hay để trả lời câu hỏi của anh ấy và chứng minh đây không phải là hằng số biên dịch – mtijn

+0

'RuntimeTypeHandle' là một hằng số. – leppie

+0

RuntimeTypeHandle là một cấu trúc. Dù sao, sự thay đổi này là gì? RuntimeTypeHandle chỉ là đối số của phương thức gọi –

1

Isn't typeof(MyClass) a compile-time constant?

Đó đặc biệt biểu thức là tĩnh phân giải, vâng, nhưng typeof() được đánh giá ở thời gian thực hiện (vì generics), do đó quy tắc phải là một Cuộc gọi typeof() không phải là thời gian biên dịch.

Tôi tự hỏi liệu nó trong C# 1.0, khi không có lập luận như vậy được thực hiện ...

+1

Tôi không nghĩ generics là lý do duy nhất cho việc này. Tôi nghĩ rằng đó là bởi vì điều này hoạt động: 'typeof (ClassInExternalAssembly)'. Nó không thể được giải quyết cho đến khi lắp ráp bên ngoài thực tế được nạp, và do đó, nó không phải là hằng số. – Aidiakapi