




Единственный способ получить переменную, которой не было присвоено значение в C#, - это сделать ее локальной переменной - и в этом случае во время компиляции вы можете определить, что она не назначена определенно, попытавшись прочитать из нее: )
Я подозреваю, что вам действительно нужен Nullable<DateTime> (или DateTime? с синтаксическим сахаром C#) - начните с null, а затем присвойте обычное значение DateTime (которое будет преобразовано соответствующим образом). Затем вы можете просто сравнить с null (или использовать свойство HasValue), чтобы увидеть, установлено ли «реальное» значение.
@Menol: Ну, это не говорит о разнице между полем, которому намеренно присвоено значение default(DateTime), и полем, которому изначально было присвоено именно такое значение. В основном он обрабатывает одно значение в домене как «особое и недоступное для нормального использования», что мне не нравится.
Если возможно, используйте Nullable<DateTime>.
DateTime - это тип значения, поэтому он не может быть нулевым. Если вы думаете DateTime? (Nullable) вы можете использовать:
DateTime? something = GetDateTime();
bool isNull = (something == null);
bool isNull2 = !something.HasValue;
ты имеешь в виду так:
DateTime datetime = new DateTime();
if (datetime == DateTime.MinValue)
{
//unassigned
}
или вы можете использовать Nullable
DateTime? datetime = null;
if (!datetime.HasValue)
{
//unassigned
}
Только второй из них является пуленепробиваемым. Первый предполагает что-то о ненастроенном представлении DateTime, которое не гарантируется фреймворком. Лично я считаю, что для этого сценария нужно было добавить статический член Unset.
Чтобы добавить к тому, что сказал @RupertRawnsley, вы должны фактически сравнить со значением по умолчанию (DateTime), которое является значением неназначенного DateTime. Так получилось, что оно равно MinValue, но может измениться.
Я обычно предпочитаю, где это возможно, использовать значение по умолчанию для типов значений, чтобы определить, были ли они установлены. Очевидно, что это невозможно постоянно, особенно с целыми числами, но для DateTimes, я думаю, достаточно справедливо зарезервировать MinValue для обозначения того, что оно не было изменено. Преимущество этого по сравнению с nullables состоит в том, что на одно место меньше, где вы получите исключение с нулевой ссылкой (и, вероятно, во многих местах, где вам не нужно проверять значение null перед доступом к нему!)
Я только что узнал, что GetHashCode () для неназначенного datetime всегда равен нулю. Я не уверен, что это хороший способ проверить значение null datetime, потому что я не могу найти никакой документации о том, почему отображается такое поведение.
if (dt.GetHashCode()==0)
{
Console.WriteLine("DateTime is unassigned");
}
GetHashCode возвращает 0, поскольку тики (внутреннее представление DateTime) также равны 0. Хеш-код рассчитывается следующим образом: unchecked((int)ticks) ^ (int)(ticks >> 32);. Также смотрите здесь: linksource.microsoft.com/#mscorlib/system/datetime.cs,8 36Большое Вам спасибо. Я пытаюсь сериализовать XML-файл из класса C# и исключить нулевые атрибуты. Это помогло.
Я бы сказал, что значение по умолчанию всегда new DateTime(). Итак, мы можем написать
DateTime datetime;
if (datetime == new DateTime())
{
//unassigned
}
Это Решение уже было предоставлено + Hath в 2008 году и, как добавил + Руперт Ронсли в качестве комментария, не является пуленепробиваемым ...
поместите это где-нибудь:
public static class DateTimeUtil //or whatever name
{
public static bool IsEmpty(this DateTime dateTime)
{
return dateTime == default(DateTime);
}
}
потом:
DateTime datetime = ...;
if (datetime.IsEmpty())
{
//unassigned
}
Мне нравится эта идея, но обратите внимание, что в несколько маловероятном случае, когда переменной DateTime было присвоено значение, которое оказывается значением по умолчанию, этот метод расширения вернет неправильный результат. Единственный способ избежать этого - использовать DateTime, допускающий значение NULL, что уже предлагалось. Тем не менее, мне все еще очень нравится (и я использую) ваш ответ, спасибо!
@Klicker: Спасибо за хороший комментарий, но я не уверен, что понимаю ваше замечание. Насколько я могу судить, == в этом случае всегда будет возвращать true, когда datetime эквивалентно значению по умолчанию (DateTime), независимо от того, каким образом datetime в конечном итоге получает значение по умолчанию. Позвольте мне объяснить: на самом деле второй фрагмент в моем ответе неверен, он не будет компилироваться, потому что, если вы считаете, что это тело функции, тогда datetime не назначено, и компилятор откажется его использовать. Поэтому вам нужно будет присвоить ему значение. Это может быть значение по умолчанию (DateTime) прямо или косвенно. Я изменю свой ответ.
и если в другом контексте datetime является членом класса и остается как есть, среда выполнения назначит ему значение по умолчанию (DateTime). Знак == для структур фактически сравнивает содержимое структуры, независимо от того, каким образом структура в конечном итоге заполнилась этим содержимым.
Моя точка зрения на самом деле относится только к ученикам, и я имею в виду; если у вас есть поле или свойство DateTime уровня класса, которому вы присвоили MinValue, ваш метод IsEmpty вернет true, что, вероятно, не то, что вам нужно (потому что нет пусто - ему присвоено значение по умолчанию). Думаю, название вашего метода больше подошло бы как IsDefaultValue. Поскольку у вас действительно не может быть DateTime, не допускающего значения NULL, что IsEmpty.
@Klicker: ах да, хорошо, понял. Вы правы: выбранное мной имя вводит в заблуждение. IsDefaultValue было бы лучше
Если вы не хотите беспокоиться о проблемах с нулевым значением, например о проверке нулевого значения каждый раз, когда вы его используете или оборачиваете его в какую-то логику, и вы также не хотите беспокоиться о проблемах времени смещения, тогда это как я решил проблему:
startDate = startDate <= DateTime.MinValue.AddSeconds(1) ? keepIt : resetIt
Я просто проверяю, что значение по умолчанию меньше, чем через день после начала времени. Работает как шарм.
Изменить 2021 год: если вам нужно проверить миллисекунды начала времени, просто добавьте вместо этого галочки, но также, возможно, датирование углерода - это то, что вы действительно ищете. Все еще не уверен, что датирование углерода будет настолько точным, насколько вам нужно, если вам нужна точность до клеща.
как насчет 00:00: 01.0000000 UTC, 1 января 0001 года?
@MahdiHesari Я не совсем уверен, что понимаю. Начало времен немного экстремально. Если вам действительно нужно вернуться к этому моменту, то я рекомендую датирование по углероду?
@MahdiHesari Я обновился, чтобы уловить ваш отличный пример с точностью до секунды с начала времен. Ценить!
как насчет проверки, равно ли значение значению даты и времени по умолчанию. Есть ли у такого подхода незаметные недостатки? if (request.StartDateTime == default (DateTime) {request.StartDateTime = DateTime.Now;}