Как мне использовать дату и время.Попробуйте проанализировать с помощью обнуляемого?

#c# #datetime #nullable

Вопрос:

Я хочу использовать дату и время.Метод TryParse для преобразования значения даты и времени строки в значение, допускающее значение Null. Но когда я попробую это:

 DateTime? d;
bool success = DateTime.TryParse("some date text", out (DateTime)d);
 

компилятор говорит мне

аргумент «out» не классифицируется как переменная

Не уверен, что мне нужно здесь делать. Я тоже пытался:

 out (DateTime)d.Value 
 

и это тоже не работает. Есть какие-нибудь идеи?

Ответ №1:

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

 public static DateTime? TryParse(string text)
{
    DateTime date;
    if (DateTime.TryParse(text, out date))
    {
        return date;
    }
    else
    {
        return null;
    }
}
 

… или, если вам нравится условный оператор:

 public static DateTime? TryParse(string text)
{
    DateTime date;
    return DateTime.TryParse(text, out date) ? date : (DateTime?) null;
}
 

Или в C# 7:

 public static DateTime? TryParse(string text) =>
    DateTime.TryParse(text, out var date) ? date : (DateTime?) null;
 

Комментарии:

1. Наверное, мне не следовало бы спорить со Скитом, но… вы должны вызвать свой метод Parse, так как я ожидал бы, что метод под названием TryParse будет следовать соглашению TryParse и возвращать логическое значение. 😉

2. @Myster: Ну, ни в том, ни в другом случае это не соответствует точному существующему соглашению — те, кто привык, просто Parse ожидали бы, что оно вернется DateTime и выдаст исключение при сбое, верно? Но да, ты можешь делать все, что захочешь… и во время Noda я вместо этого назвал соответствующие методы Parse .

3. else Ключевое слово не является необходимым (в вашем первом примере), так как конечная точка if блока никогда не может быть достигнута.

4. @JeppeStigNielsen: Да, в этом нет необходимости, но это может быть стилистически предпочтительнее для симметрии. Это просто личное предпочтение (и я тоже не последователен…)

5. @Kiquenet: использование else проясняет, что будет выбран тот или иной путь, и оба вернутся. Я против массивно вложенного кода, но в данном случае это действительно не проблема, ИМО.

Ответ №2:

 DateTime? d=null;
DateTime d2;
bool success = DateTime.TryParse("some date text", out d2);
if (success) d=d2;
 

(Могут быть и более элегантные решения, но почему бы вам просто не сделать что-то, как описано выше?)

Комментарии:

1. Вы правы, я искал более простой способ сделать это, но я полагаю, что этого будет достаточно. Не нравится создавать эту временную переменную, чувствуется беспорядок. :-/ Похоже, этот сценарий следует лучше поддерживать.

2. смотрите предложение Binary Worrier для psuedo-встроить это в метод расширения.

3. Почему вы переводите дату — время в дату-время? Вам не нужно переделывать d2 перед передачей его в пробный анализ.

4. @Slace-я обновил ответ, чтобы включить ваше предложение.

5. @Jason Kealey Я надеюсь, что это уже будет представлено в VS2012, иначе мне придется продолжать использовать этот хороший фрагмент кода.

Ответ №3:

Вот слегка сокращенное изложение того, что предложил Джейсон:

 DateTime? d; DateTime dt;
d = DateTime.TryParse(DateTime.Now.ToString(), out dt)? dt : (DateTime?)null;
 

Ответ №4:

Вы не можете, потому Nullable<DateTime> что это другой тип DateTime . Для этого вам нужно написать свою собственную функцию,

 public bool TryParse(string text, out Nullable<DateTime> nDate)
{
    DateTime date;
    bool isParsed = DateTime.TryParse(text, out date);
    if (isParsed)
        nDate = new Nullable<DateTime>(date);
    else
        nDate = new Nullable<DateTime>();
    return isParsed;
}
 

Надеюсь, это поможет 🙂

ИЗМЕНИТЬ: Удален (очевидно) неправильно протестированный метод расширения, потому что (как указано некоторыми плохими учителями) методы расширения, которые пытаются изменить параметр «this», не будут работать с типами значений.

P.S. Плохая Шлюха, о которой идет речь, — мой старый друг 🙂

Комментарии:

1. Ты не хочешь вводить дату [так как ты используешь ее как выходной параметр] Хорошо, я перестану быть придирчивым!

2. У меня нет компилятора, но, поскольку DateTime является типом значения, компилируется ли метод расширения def?

3. Результат не возвращается, если вы не сделаете это — [TestFixture] публичный класс при расширении { [Тест] публичная пустота TryParseShouldWork() { Дата и время? x = ноль; var res = Внешние. Попробуйте проанализировать( x, «1/1/1990» ); Утверждайте. ИСТРУ( res )

4. ;Утверждать. Это( x != null ); } } сбой при утверждении. Это, т. е. результат не изменяется, поскольку DateTime является типом значения (что всегда является хорошим вопросом для исключения на экранах телефонов :D)

5. (obv первый (без расширения) будет работать, но он должен быть отключен, а не ref-и вы должны аннулировать результат, если он не соответствует API TryXXX в целом — Почти уверен, что FDG упоминает об этом. Блин, какой же я придирчивый!

Ответ №5:

Как насчет создания метода расширения?

 public static class NullableExtensions
{
    public static bool TryParse(this DateTime? dateTime, string dateString, out DateTime? result)
    {
        DateTime tempDate;
        if(! DateTime.TryParse(dateString,out tempDate))
        {
            result = null;
            return false;
        }

        result = tempDate;
        return true;

    }
}
 

Комментарии:

1. Для чего нужен этот первый параметр, dateTime ,? Он никогда не используется.

2. @mikez — вот как работают методы расширения, компилятор использует их, чтобы знать, что это должен быть метод расширения.

3. @MystereMan Я знаю, что такое метод расширения. Более подходящей подписью для метода расширения была бы DateTime? TryParse(this string dateString) . Эта реализация просто странная.

4. @mikez — тогда почему ты спросил, для чего это было? Зачем загрязнять пространство имен строк, если оно нужно только для даты и времени? Цель состоит в том, чтобы обеспечить аналог даты и времени. Попробуйте проанализировать, что такое дата-время?. Попробуйте проанализировать

5. @ErikFunkenbusch Этот метод расширения не допускает синтаксис вызова, подобный (DateTime?).TryParse( ... ) или Nullable<DateTime>.TryParse( ... ) . Так что Майк зи прав, это глупая подпись для метода.

Ответ №6:

Я не понимаю, почему Microsoft не справилась с этим. Умный маленький полезный метод для решения этой проблемы (у меня была проблема с int, но замена int на DateTime будет иметь тот же эффект, может быть…..

     public static bool NullableValueTryParse(string text, out int? nInt)
    {
        int value;
        if (int.TryParse(text, out value))
        {
            nInt = value;
            return true;
        }
        else
        {
            nInt = null;
            return false;
        }
    }
 

Ответ №7:

Вот однострочное решение:

 DateTime? d = DateTime.TryParse("text", out DateTime parseDate) ? parseDate : (DateTime?)null;
 

Комментарии:

1. итак…вы только что скопировали мой ответ 4 месяца спустя?

Ответ №8:

Это тот лайнер, который вы ищете:

 DateTime? d = DateTime.TryParse("some date text", out DateTime dt) ? dt : null;
 

Если вы хотите сделать его подходящим методом псевдо-расширения TryParse, вы можете сделать это:

 public static bool TryParse(string text, out DateTime? dt)
{
    if (DateTime.TryParse(text, out DateTime date))
    {
        dt = date;
        return true;
    }
    else
    {
        dt = null;
        return false;
    }
}
 

Комментарии:

1. @robnick, чем это отличается от того, что я сказал?

2. Проигнорируйте мой предыдущий комментарий (я поддержал ваше решение!), для последней версии C# мне нужно было ввести значение null: дата-время? d = Дата и время. Попробуйте проанализировать(бла, дата и время dt) ? dt : (Дата и время?)значение null;

Ответ №9:

В качестве альтернативы, если вас не беспокоит возможное возникшее исключение, вы можете изменить пробный анализ для разбора:

 DateTime? d = DateTime.Parse("some valid text");
 

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