Почему DateTime.MinValue нельзя использовать в качестве необязательного параметра в C # - PullRequest
18 голосов
/ 24 января 2012

Я писал метод, который принимает значение 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()?

Ответы [ 7 ]

12 голосов
/ 24 января 2012

DateTime.MinValue определяется как:

public static readonly DateTime MinValue

Что не совпадает с const. Так как значение readonly не является константой времени компиляции (то есть значение не оценивается во время компиляции), его нельзя использовать.

Причина использования new DateTime() в том, что это выражение известно во время компиляции. Это то же самое, что написать default(DateTime). Например, result == true в следующем выражении:

var result = new DateTime() == default(DateTime);
9 голосов
/ 24 января 2012

Другие ответы касаются того, почему DateTime.MinValue нельзя использовать, это не допустимая постоянная времени компиляции.Это поле static readonly, которое вполне может быть константным с точки зрения использования, но не является юридически константой и не соответствует правилам того, что может использоваться в качестве аргумента по умолчанию.Относительно того, почему new DateTime() можно использовать , см. Раздел 10.6.1 спецификации языка C # 4.0 .Соответствующие биты:

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

· выражение-константы

· выражениеформа new S (), где S - тип значения

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

В результате получается экземпляр с нулевой инициализацией, в основном битовый набор всех нулей.(См .: Раздел 4.1.2)

Однако в этом случае я все же рекомендую использовать DateTime? value = null в качестве параметра и аргумента по умолчанию, особенно когда он представляет собой обнуляемую дату в базе данных.MinValue - это не отсутствие значения.null есть.

5 голосов
/ 24 января 2012

DateTime.MinValue равно только для чтения , и согласно MSDN значения только для чтения не являются константами времени компиляции:

Ключевое слово readonly отличается от ключевого слова const. Константное поле может быть инициализировано только при объявлении поля. Поле только для чтения может быть инициализировано либо в объявлении, либо в конструкторе. Поэтому поля только для чтения могут иметь разные значения в зависимости от используемого конструктора. Кроме того, хотя поле const является константой времени компиляции, поле readonly может использоваться для констант времени выполнения

4 голосов
/ 24 января 2012

DateTime.MinValueDateTime.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 ) ;

}
3 голосов
/ 24 января 2012

Другой альтернативой может быть перегрузка двух методов:

  • Тот, который принимает параметр DateTime
  • Тот, который не принимает параметр DateTime

Преимущество этого в том, что вам не нужно проверять, имеет ли параметр значение NULL, и было бы ясно, каково ваше намерение. Внутри метод 1 может добавить ноль в базу данных.

1 голос
/ 24 января 2012

на основании того, что мне известно, что значением по умолчанию для DateTime является DateTime.MinValue, так почему бы просто не использовать новый DateTime ()

0 голосов
/ 14 декабря 2015

Используйте это утверждение

private void test(string something, DateTime testVar = new DateTime()) {
    if ( testVar != new DateTime() )
    {
        DoSomethingUsefulWithTimestamp( something , testVar.Value ) ;
    }
    else
    {
        DoSomethingElseWithoutTimestamp( something ) ;
    }
}

Это должно работать намного лучше. Это облом, что нуль не работает, потому что это имеет больше смысла.

...