Подтвердить что ты не робот

Почему С# не разрешает typeof как параметр по умолчанию?

class MyClass
{
    public void MyMethod(Type targetType = typeof(MyClass))
    {
    }
}

Не typeof(MyClass) константа времени компиляции?

4b9b3361

Ответ 1

От MSDN - Именованные и необязательные параметры:

Значение по умолчанию должно быть одним из следующих типов выражений:

  • постоянное выражение;

  • выражение формы new ValType(), где ValType - тип значения, такой как перечисление или структура;

  • выражение формы по умолчанию (ValType), где ValType - тип значения.


typeof необязательно возвращает константу времени компиляции, так как она может возвращать разные результаты в зависимости от контекста.

Ответ 2

Я не эксперт 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 

Вы можете видеть, что это не постоянный тип записи кода:

const Type constType = typeof(int);

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

Constant initialize must be compile-time constant

Ответ 3

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

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

Ответ 4

Не typeof(MyClass) константа времени компиляции?

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

Я действительно задаюсь вопросом, было ли это в С# 1.0, когда такого аргумента не было...

Ответ 5

Это старый, но если кто-то ищет обходной путь:

    class MyClass
    {
        public void MyMethod(Type targetType = null)
        {
            if(targetType == null)
            {
                targetType = typeof(MyClass);
            }
        }
    }