Оба из них генерируют ошибку при высказывании, что они должны быть постоянным временем компиляции:
void Foo(TimeSpan span = TimeSpan.FromSeconds(2.0))
void Foo(TimeSpan span = new TimeSpan(2000))
В первую очередь, кто-то может объяснить, почему эти значения не могут быть определены во время компиляции? И существует ли способ указать значение по умолчанию для дополнительного объекта TimeSpan?
Вы можете легко справиться с этим, изменив свою подпись.
void Foo(TimeSpan? span = null) {
if (span == null) { span = TimeSpan.FromSeconds(2); }
...
}
Следует уточнить - причина, по которой эти выражения в Вашем примере не являются константами времени компиляции, заключается в том, что при компиляции компилятор не может просто выполнить TimeSpan.FromSeconds(2.0) и вставить байты результата в скомпилированный Вами код.
В качестве примера рассмотрим, если Вы пытались использовать DateTime.Now вместо этого. Значение DateTime.Now меняется каждый раз при его выполнении. Или предположим, что TimeSpan.FromSeconds учитывал гравитацию. Это абсурдный пример, но правила компиляции констант времени не делают особых случаев только потому, что мы случайно знаем, что TimeSpan.FromSeconds детерминирован.
Набор значений, которые можно использовать в качестве значения по умолчанию, тот же, что и для аргумента атрибута. Причина в том, что значения по умолчанию кодируются в метаданные внутри DefaultParameterValueAttribute
.
Относительно того, почему это не может быть определено во время компиляции. Набор значений и выражений для таких значений, разрешенных во время компиляции, указан в официальной спецификации языка C # :
C # 6.0 - Типы параметров атрибутов :
Типы позиционных и именованных параметров для класса атрибутов ограничены типами параметров атрибутов , а именно:
- Один из следующих типов:
bool
,byte
,char
,double
,float
,int
,long
,sbyte
,short
],строка
,uint
,ulong
,ushort
.- Тип
объект
.- Тип
System.Type
.- Тип перечисления.
(при условии, что он общедоступен, а типы, в которые он вложен (если есть), также имеют общедоступный доступ)- Одномерные массивы вышеуказанных типов.
Тип TimeSpan
не помещается ни в один из этих списков и, следовательно, не может использоваться в качестве константы.