C# 4.0: я могу использовать TimeSpan в качестве дополнительного параметра со значением по умолчанию?

Оба из них генерируют ошибку при высказывании, что они должны быть постоянным временем компиляции:

void Foo(TimeSpan span = TimeSpan.FromSeconds(2.0))
void Foo(TimeSpan span = new TimeSpan(2000))

В первую очередь, кто-то может объяснить, почему эти значения не могут быть определены во время компиляции? И существует ли способ указать значение по умолчанию для дополнительного объекта TimeSpan?

117
задан BoltClock 8 August 2011 в 21:28
поделиться

2 ответа

Вы можете легко справиться с этим, изменив свою подпись.

void Foo(TimeSpan? span = null) {

   if (span == null) { span = TimeSpan.FromSeconds(2); }

   ...

}

Следует уточнить - причина, по которой эти выражения в Вашем примере не являются константами времени компиляции, заключается в том, что при компиляции компилятор не может просто выполнить TimeSpan.FromSeconds(2.0) и вставить байты результата в скомпилированный Вами код.

В качестве примера рассмотрим, если Вы пытались использовать DateTime.Now вместо этого. Значение DateTime.Now меняется каждый раз при его выполнении. Или предположим, что TimeSpan.FromSeconds учитывал гравитацию. Это абсурдный пример, но правила компиляции констант времени не делают особых случаев только потому, что мы случайно знаем, что TimeSpan.FromSeconds детерминирован.

165
ответ дан 24 November 2019 в 02:06
поделиться

Набор значений, которые можно использовать в качестве значения по умолчанию, тот же, что и для аргумента атрибута. Причина в том, что значения по умолчанию кодируются в метаданные внутри DefaultParameterValueAttribute .

Относительно того, почему это не может быть определено во время компиляции. Набор значений и выражений для таких значений, разрешенных во время компиляции, указан в официальной спецификации языка C # :

C # 6.0 - Типы параметров атрибутов :

Типы позиционных и именованных параметров для класса атрибутов ограничены типами параметров атрибутов , а именно:

  • Один из следующих типов: bool , byte , char , double , float , int , long , sbyte , short ], строка , uint , ulong , ushort .
  • Тип объект .
  • Тип System.Type .
  • Тип перечисления.
    (при условии, что он общедоступен, а типы, в которые он вложен (если есть), также имеют общедоступный доступ)
  • Одномерные массивы вышеуказанных типов.

Тип TimeSpan не помещается ни в один из этих списков и, следовательно, не может использоваться в качестве константы.

15
ответ дан 24 November 2019 в 02:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: