Как использовать DateTime.TryParse с Nullable <DateTime>?

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

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

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

'out' argument is not classified as a variable

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

out (DateTime)d.Value 

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
120
0
103 228
9
Перейти к ответу Данный вопрос помечен как решенный

Ответы 9

Ответ принят как подходящий

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

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

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

Brian Sullivan 10.10.2008 20:39

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

David Alpert 10.10.2008 20:48

Почему вы приводите DateTime к DateTime? Вам не нужно повторно использовать d2 перед его передачей в TryParse.

Aaron Powell 01.11.2008 00:48

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

Drew Noakes 31.05.2010 13:27

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

Pimenta 13.11.2012 14:50

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

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;

Я, вероятно, не должен спорить с The Skeet, но ... вы должны вызвать свой метод Parse, поскольку я ожидаю, что метод с именем TryParse будет следовать соглашению TryParse и возвращать логическое значение. ;-)

Myster 13.04.2015 01:09

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

Jon Skeet 13.04.2015 09:01

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

Jeppe Stig Nielsen 24.01.2017 13:25

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

Jon Skeet 24.01.2017 13:31

Избегайте Стрелка анти-узорelse { return null; } от return null; Просмотр: blog.codinghorror.com/flattening-arrow-code

Kiquenet 10.06.2017 21:10

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

Jon Skeet 10.06.2017 21:12

Вы не можете, потому что 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. Речь идет о Bad Hoor - старый друг :)

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

Ruben Bartelink 16.01.2009 15:55

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

Ruben Bartelink 16.01.2009 15:59

Результат не вернется, пока вы его не добьетесь - [TestFixture] открытый класс WhenExnding {[Test] public void TryParseShouldWork () {DateTime? х = ноль; var res = Externders.TryParse (x, «01.01.1990»); Assert.IsTrue (res)

Ruben Bartelink 16.01.2009 17:22

; Assert.That (x! = Ноль); }} не работает в Assertthat, т.е. результат не изменяется, поскольку DateTime является типом значения (что всегда является хорошим вопросом для исключения на экранах телефонов: D)

Ruben Bartelink 16.01.2009 17:23

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

Ruben Bartelink 16.01.2009 17:25

Очевидно, что показанные образцы предназначены для иллюстрации. . . (и Рубен ПРЕКРАТИТЕ СВОИ НИЧЕГО ВЫБИРАЮТ ВАМ ПЛОХО!)

Binary Worrier 16.01.2009 17:32

P.S. . . . и что это за «Тесты» и «Утверждения», о которых вы говорите? (Расскажи мне о своем родном мире усул)

Binary Worrier 16.01.2009 17:34

Рубен: Вы правы, товарищ, метод расширения не подойдет для этого (или любого другого типа значения). Хорошо подмечено . . . кашель я плохой кашель

Binary Worrier 16.01.2009 18:02

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

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

Я не понимаю, почему 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;
        }
    }

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

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;

    }
}

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

Mike Zboray 21.10.2012 10:07

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

Erik Funkenbusch 11.02.2013 23:56

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

Mike Zboray 12.02.2013 00:07

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

Erik Funkenbusch 12.02.2013 00:18

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

Jeppe Stig Nielsen 24.01.2017 13:30

@JeppeStigNielsen - Вы, очевидно, не понимаете, как работают методы расширения. Вы не называете их статическими методами. Вы вызываете их как обычные методы, такие как variablename.TryParse(), а не typename.TryParse().

Erik Funkenbusch 29.01.2017 19:11

@ErikFunkenbusch Да, вы правы. Обсуждение здесь заключается в том, что использование this DateTime? dateTimeкогда этот параметр не используется в теле метода? Это оригинальный вопрос Майка З. Если бы кто-то использовал метод этого ответа, он должен был бы сделать это: DateTime? dummy = null; DateTime? result; var isSuccess = dummy.TryParse("some date text", out result);. В противном случае следует сначала присвоить значение переменной out, а также использовать переменную outresult в качестве «специального» аргумента this, что кажется странным. Так можем ли мы лучше ответить на первый комментарий Майка З.?

Jeppe Stig Nielsen 29.01.2017 19:52

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

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

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

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

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;
    }
}

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

cpcolella 13.12.2019 06:00

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

robnick 14.12.2019 07:09

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

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

Другие вопросы по теме