Я смотрю на то, как определяется ParameterInfo.IsOptional
(я добавляю поддержку параметров по умолчанию во внутреннюю структуру IOC), и мне кажется, что при истинном значении нет гарантии, что ParameterInfo.DefaultValue
(или действительно ParameterInfo.RawDefaultValue
) на самом деле значения по умолчанию, которые должны быть применены.
Если вы посмотрите на пример MSDN, приведенный для IsOptional
, в IL можно определить параметр, который является необязательным, но для которого не задано значение по умолчанию (учитывая, что ParameterAttributes.HasDefault
должен быть явно предоставлено). То есть потенциально может привести к ситуации, когда тип параметра, скажем, Int32
, ParameterInfo.IsOptional
- истина, но ParameterInfo.DefaultValue
- ноль.
Мой язык - C #, поэтому я могу работать над тем, что сделает компилятор . Исходя из этого, я могу провести простой тест следующим образом (parameter
здесь есть экземпляр ParameterInfo
, и метод предназначен для возврата экземпляра, который будет использоваться в качестве аргумента времени выполнения для параметра):
if(no_config_value)
{
if(!parameter.IsOptional) throw new InvalidOperationException();
//it's optional, so read the Default
return parameter.DefaultValue;
}
else
return current_method_for_getting_value();
Но я думаю, что некоторые языки (и я хочу получить это право на уровне IL, а не просто на основе того, что делает один конкретный компилятор) могут перекладывать ответственность на вызывающую сторону на определить значение по умолчанию, которое будет использоваться, если так, то default(parameter.ParameterType)
должен быть в порядке.
Здесь все становится немного интереснее, потому что DefaultValue
, по-видимому, DBNull.Value
(согласно документации для RawValue
), если по умолчанию нет. Что не хорошо, если параметр имеет тип object
и IsOptional==true
!
Сделав немного больше копания, я надеюсь, что надежный способ решить эту проблему - это физически прочитать элемент ParameterInfo.Attributes
, читая битовые флаги индивидуально сначала , чтобы проверить ParameterAttributes.Optional
и , затем проверьте ParameterAttributes.Default
. Только если оба присутствуют, тогда значение ParameterInfo.DefaultValue
будет правильным.
Я собираюсь начать кодирование и написание тестов вокруг этого, но я спрашиваю в надежде, что есть кто-то с большим знанием IL, который может подтвердить мои подозрения и надеюсь, что это будет правильным для любого основанного на IL язык (таким образом, избегая необходимости макетировать множество библиотек на разных языках!).