Я хочу использовать метод 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
и это тоже не работает. Есть идеи?





DateTime? d=null;
DateTime d2;
bool success = DateTime.TryParse("some date text", out d2);
if (success) d=d2;
(Могут быть более элегантные решения, но почему бы вам просто не сделать что-то, как указано выше?)
см. предложение Binary Worrier псевдо-встроить это в метод расширения.
Почему вы приводите DateTime к DateTime? Вам не нужно повторно использовать d2 перед его передачей в TryParse.
@Slace - Я обновил ответ, чтобы включить ваше предложение.
@Jason Kealey Я надеюсь, что это уже введено в VS2012, иначе мне придется продолжать использовать этот хороший фрагмент кода.
Как говорит Джейсон, вы можете создать переменную правильного типа и передать ее. Возможно, вы захотите инкапсулировать его в свой собственный метод:
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: Ну, в любом случае он не соответствует точному существующему соглашению - те, кто привык только к Parse, ожидали бы, что он вернет DateTime и выдаст исключение при ошибке, верно? Но да, вы можете делать все, что хотите ... и в Noda Time вместо этого я назвал соответствующие методы Parse.
Ключевое слово else не нужно (в вашем первом примере), поскольку конечная точка блока if никогда не может быть достигнута.
@JeppeStigNielsen: Да, в этом нет необходимости, но это может быть стилистически предпочтительнее для симметрии. Это просто личное предпочтение (и я тоже не согласен ...)
Избегайте Стрелка анти-узорelse { return null; } от return null; Просмотр: blog.codinghorror.com/flattening-arrow-code
@Kiquenet: использование else делает более ясным, что будет выбран тот или иной путь, и оба вернутся. Я против массового вложенного кода, но в данном случае это не проблема, ИМО.
Вы не можете, потому что 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 - старый друг :)
Я не хочу инициировать дату [поскольку вы используете это как выходной параметр] Хорошо, я перестану быть разборчивым!
У меня нет компилятора, но поскольку DateTime является типом значения, компилируется ли метод расширения def?
Результат не вернется, пока вы его не добьетесь - [TestFixture] открытый класс WhenExnding {[Test] public void TryParseShouldWork () {DateTime? х = ноль; var res = Externders.TryParse (x, «01.01.1990»); Assert.IsTrue (res)
; Assert.That (x! = Ноль); }} не работает в Assertthat, т.е. результат не изменяется, поскольку DateTime является типом значения (что всегда является хорошим вопросом для исключения на экранах телефонов: D)
(obv первый (нерасширенный) будет работать, но он должен быть отключен, а не ref - и вы должны обнулить результат, если он не соответствует API TryXXX в целом - почти наверняка FDG упоминает об этом. Я придирчив!
Очевидно, что показанные образцы предназначены для иллюстрации. . . (и Рубен ПРЕКРАТИТЕ СВОИ НИЧЕГО ВЫБИРАЮТ ВАМ ПЛОХО!)
P.S. . . . и что это за «Тесты» и «Утверждения», о которых вы говорите? (Расскажи мне о своем родном мире усул)
Рубен: Вы правы, товарищ, метод расширения не подойдет для этого (или любого другого типа значения). Хорошо подмечено . . . кашель я плохой кашель
Вот немного сжатое издание того, что предложил Джейсон:
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? Никогда не используется.
@mikez - так работают методы расширения, он используется компилятором, чтобы знать, что это должен быть метод расширения.
@MystereMan Я знаю, что такое метод расширения. Более подходящей подписью для метода расширения будет DateTime? TryParse(this string dateString). Это просто причудливая реализация.
@mikez - тогда почему ты спросил, для чего это было? Зачем загрязнять пространство имен строк, когда оно нужно только для datetime? Цель состоит в том, чтобы предоставить аналог DateTime.TryParse, то есть DateTime? .TryParse
@ErikFunkenbusch Этот метод расширения нет разрешает синтаксис вызова, такой как (DateTime?).TryParse( ... ) или Nullable<DateTime>.TryParse( ... ). Итак, Майк z прав, это глупая подпись метода.
@JeppeStigNielsen - Вы, очевидно, не понимаете, как работают методы расширения. Вы не называете их статическими методами. Вы вызываете их как обычные методы, такие как variablename.TryParse(), а не typename.TryParse().
@ErikFunkenbusch Да, вы правы. Обсуждение здесь заключается в том, что использование this DateTime? dateTimeкогда этот параметр не используется в теле метода? Это оригинальный вопрос Майка З. Если бы кто-то использовал метод этого ответа, он должен был бы сделать это: DateTime? dummy = null; DateTime? result; var isSuccess = dummy.TryParse("some date text", out result);. В противном случае следует сначала присвоить значение переменной out, а также использовать переменную outresult в качестве «специального» аргумента this, что кажется странным. Так можем ли мы лучше ответить на первый комментарий Майка З.?
В качестве альтернативы, если вас не беспокоит возможное возникшее исключение, вы можете изменить 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 Чем это отличается от того, что я сказал?
Не обращайте внимания на мой предыдущий комментарий (я поддержал ваше решение!), Для последней версии C# мне нужно было указать null: DateTime? d = DateTime.TryParse (мля, нет DateTime dt)? dt: (DateTime?) null;
Вот однострочное решение:
DateTime? d = DateTime.TryParse("text", out DateTime parseDate) ? parseDate : (DateTime?)null;
Вы правы, я искал больше однострочного, чтобы сделать это, но я полагаю, что это сойдет. Не люблю создавать эту временную переменную, кажется беспорядочным. : - / Похоже, этот сценарий лучше поддерживать.