Почему DateTime.MinValue не может использоваться как необязательный параметр в С#
Я писал метод, который принимает значение DateTime
как один из его параметров. Я решил, что это необязательный параметр, поэтому я пошел вперед и попытался сделать DateTime.MinValue
по умолчанию.
private void test(string something, DateTime testVar = DateTime.MinValue) {
}
Однако это дает ошибку:
Значение параметра по умолчанию для 'testVar' должно быть константой времени компиляции.
Использование этого кода, похоже, очень хорошо работает.
private void test(string something, DateTime testVar = new DateTime()) {
}
Мне было предложено использовать DateTime.MinValue вместо нового DateTime(), поскольку оно самодокументируется. Поскольку new DateTime()
в основном то же самое, почему DateTime.MinValue
нельзя использовать? Также будет какая-либо потенциальная проблема, если я оставлю ее с помощью new DateTime()
?
Ответы
Ответ 1
DateTime.MinValue
определяется как:
public static readonly DateTime MinValue
Это не то же самое, что const
. Поскольку значение readonly
не является константой времени компиляции (т.е. Значение не оценивается во время компиляции), его нельзя использовать.
Причина, по которой работает new DateTime()
, заключается в том, что это выражение известно во время компиляции. Это то же самое, что писать default(DateTime)
. Например, result == true
в следующем выражении:
var result = new DateTime() == default(DateTime);
Ответ 2
Другие ответы касаются того, почему DateTime.MinValue не может использоваться, это не постоянная постоянная времени компиляции. Это поле static readonly
, которое вполне может быть постоянным по мере использования, но не является юридически постоянным и не соответствует правилам того, что можно использовать в качестве аргумента по умолчанию. Что касается использования new DateTime()
, см. Раздел 10.6.1 С# 4.0 Language Specification. Соответствующие биты:
Выражение в аргументе по умолчанию должно быть одним из следующих:
· константное выражение
· выражение формы new S(), где S - тип значения
выражение формы по умолчанию (S), где S - тип значения
Это приводит к нулевому инициализированному экземпляру, в основном битовой схеме всех нулей. (См.: Раздел 4.1.2)
Однако в этом случае я по-прежнему рекомендую использовать параметр DateTime? value = null
как параметр и аргумент по умолчанию, особенно когда он представляет дату с нулевым значением в базе данных. MinValue
- это не отсутствие значения. null
есть.
Ответ 3
DateTime.MinValue readonly, и согласно MSDN значения readonly не являются константами времени компиляции:
Ключевое слово readonly отличается от ключевого слова const. Поле const может быть инициализировано только при объявлении поля. Поле readonly может быть инициализировано либо в объявлении, либо в конструкторе. Поэтому поля readonly могут иметь разные значения в зависимости от используемого конструктора. Кроме того, хотя поле const является константой времени компиляции, поле readonly может использоваться для констант времени выполнения
Ответ 4
DateTime.MinValue
(и DateTime.MaxValue
) являются членами public static readonly
, а не константами времени компиляции.
Вместо того, чтобы использовать DateTime.MinValue
как ваш по умолчанию, почему бы не использовать значение DateTime (DateTime?
) с нулевым значением. Это делает ваше намерение более ясным, чем невыполнение минимального значения datetime.
Что-то вроде этого:
private void test(string something, DateTime? testVar = null )
{
if ( testVar.HasValue )
{
DoSomethingUsefulWithTimestamp( something , testVar.Value ) ;
}
else
{
DoSomethingElseWithoutTimestamp( something ) ;
}
return ;
}
private void DoSomethingUsefulWithTimestamp( string something , DateTime dt )
{
... // something useful
}
private void DoSomethingElseWithoutTimestamp( string something )
{
... // something useful
}
В качестве альтернативы, установите свое значение по умолчанию в своем теле метода:
private void test(string something, DateTime? testVar = null )
{
DateTime dtParameter = testVar ?? DateTime.MinValue ;
DoSomethingUsefulWithTimestamp( something , dtParameter ) ;
}
Ответ 5
Другим вариантом было бы иметь 2 метода перегрузки:
- Тот, который принимает параметр DateTime
- Тот, который не принимает параметр DateTime
Преимущество этого в том, что вам не нужно было бы проверять, является ли параметр нулевым, и было бы ясно, каково ваше намерение. Внутри метод 1 может добавить нуль в базу данных.
Ответ 6
на основе того, что мне известно о значении по умолчанию для DateTime, является DateTime.MinValue, поэтому почему бы просто не использовать новую DateTime()
Ответ 7
Используйте это утверждение
private void test(string something, DateTime testVar = new DateTime()) {
if ( testVar != new DateTime() )
{
DoSomethingUsefulWithTimestamp( something , testVar.Value ) ;
}
else
{
DoSomethingElseWithoutTimestamp( something ) ;
}
}
Он должен работать намного лучше. Это облом, что null не работает, потому что это имеет смысл.