2012-01-20 3 views

ответ

5

Из 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 не обязательно возвращать время компиляции константу, как она может возвращать разные результаты в зависимости от контекста.

+0

тип передается 'typeof' должны быть решены во время компиляции. Поэтому я не понимаю, что вы имеете в виду. Если то, что вы говорите, верно, атрибуты должны также запрещать «константы типов». – leppie

+0

leppie, что вы подразумеваете под «атрибутами, также должны запрещать« константы типа »? Где атрибуты ограничивают значения константами? –

+1

@Fujiy - Параметры, переданные конструкторам атрибутов, должны быть компилируемыми временными константами. – Oded

4

потому что это не обязательно постоянное выражение. ваш пример имеет типof на простом классе, но что, если класс был общим? Очевидно, это не является постоянным на сегодняшний день:

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

Я не эксперт IL, но кажется, что он вызывает метод в L_0005:

return typeof(int); 

подмигнули то же самое из:

.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 

Вы можете видеть, что isn'ta постоянного типа написания кода:

const Type constType = typeof(int); 

Это возвращает ошибку:

Constant initialize must be compile-time constant 
+2

+1 хороший способ ответить на его вопрос и доказать, что это не постоянная времени компиляции. – mtijn

+0

Однако RuntimeTypeHandle является константой. – leppie

+0

RuntimeTypeHandle - это структура. В любом случае, каково это изменение? RuntimeTypeHandle - это просто аргумент метода call –

1

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

Это частности выражение статически разрешимы, да, но typeof() оценивается во время выполнения (из-за дженериков), поэтому правило должно быть, что typeof() вызов не является константой времени компиляции.

мне интересно, что ли в C# 1.0, когда не было такого аргумента быть ...

+1

Я не думаю, что для этого единственные причины. Я думаю, это потому, что это работает: 'typeof (ClassInExternalAssembly)'. Он не может быть разрешен до тех пор, пока фактическая внешняя сборка не будет загружена, и, следовательно, она не будет постоянной. – Aidiakapi