Я действительно хочу вернуть минимальную дату?
Старый коллега по работе использовал, чтобы процитировать своего отца о инструментах: "Вы должны быть умнее, чем он".
В приведенном ниже коде, Resharper говорит мне: "Назначенное значение не используется в любом пути выполнения" (указывая на первую строку). Если я принимаю его предложение о помощи, dt не присваивается значение ( "сегодня" ).
Это случай, когда "я должен быть умнее, чем он", и игнорировать их предупреждение, или это случай, когда инструмент умнее меня, и я просто не понимаю его?
Я считаю, что если оператор if терпит неудачу, возвращается текущая дата (значение по умолчанию, которое я хочу), но если я соглашусь на Resharper "требует", он вернет значение по умолчанию для Datetime, которое является минимальная дата, которую я предполагаю, составляет примерно 7/4/1776 или 1/1/0000 или около того.
DateTime dt = DateTime.Now;
if (!(DateTime.TryParse(substr, out dt))) {
using (var dtpDlgForm = new ReturnDate("Please select the Date that the file was created:")) {
if (dtpDlgForm.ShowDialog() == DialogResult.OK) {
dt = dtpDlgForm.ReturnVal;
}
}
}
return dt;
Ответы
Ответ 1
Ваша предполагаемая логика допускает три возможных значения возврата DateTime
(в порядке предпочтения):
- Проанализированное значение
substr
.
- Значение, выбранное в диалоговом окне.
- Текущая дата и время.
Вы можете реализовать эту логику, имея отдельные операторы return
, которые выполняются, когда их условие преуспевает:
DateTime dt;
if (DateTime.TryParse(substr, out dt))
return dt;
using (var dtpDlgForm = new ReturnDate(
"Please select the Date that the file was created:"))
{
if (dtpDlgForm.ShowDialog() == DialogResult.OK)
return dtpDlgForm.ReturnVal;
}
return DateTime.Now;
Изменить. Чтобы объяснить, почему вы не должны назначать значение переменной, которая будет использоваться как параметр out
, обратитесь к Mark Байерс отвечает.
Ответ 2
Ответ, который вы приняли, показывает, что вы должны делать, но не объясняет, почему Resharper жалуется в первую очередь. Поскольку это объяснение может быть полезно для других, которые находят ваш вопрос, вот он:
Вам следует следовать рекомендациям Resharper и изменить первую строку на:
DateTime dt;
Это объявляет переменную dt
, но не присваивает ей никакого значения. Здесь нет необходимости назначать значение, потому что оно будет определенно назначено на следующей строке из-за ключевого слова out
. Из документации:
Несмотря на то, что переменные, переданные как out
, не должны быть инициализированы перед передачей, , вызываемый метод должен назначать значение до того, как метод вернет.
Акцент мой. Назначение значения DateTime.Now
не нужно и вводит в заблуждение, потому что это значение никогда не будет использоваться.
Мое отношение к ситуации заключается в том, что если оператор if терпит неудачу, возвращается текущая дата
Это не то, что делает ваш код. В документации :
result: Когда этот метод возвращает, содержит значение DateTime, эквивалентное дате и времени, содержащимся в s, если преобразование преуспело, или MinValue, если преобразование завершилось с ошибкой.
С кодом, который вы отправили, если синтаксический анализ завершился неудачей, dt
будет содержать значение DateTime.MinValue
, а не значение DateTime.Now
, которое вы назначили.
Ответ 3
Это потому, что вы назначаете значение dt, а затем передаете его в качестве out param. Если переменная передается как параметр out:
- Перед использованием в ней должно быть назначено значение внутри этой функции
- Ему необходимо присвоить значение до того, как эта функция вернет
В вашем случае вы можете исправить сообщение из сообщения ReSharper, изменив первую строку на:
DateTime dt;
Мое отношение к ситуации заключается в том, что если инструкция if терпит неудачу, текущая дата возвращается
Это неверно. Он всегда будет возвращать DateTime.MinValue, независимо от значения объекта DateTime, в который вы проходите.
Из MSDN - DateTime.TryParse(строка, вне DateTime):
результат
Тип: System.DateTime%
Когда этот метод возвращает, [результат] содержит значение DateTime эквивалентный дате и времени, содержащимся в s, если преобразование или MinValue, если преобразование завершилось неудачно. Преобразование если параметр s равен нулю, это пустая строка ("") или не содержат допустимое строковое представление даты и времени. Эта параметр передается неинициализированным.
(добавлен акцент)
Ответ 4
Параметр out
всегда имеет значение, назначенное ему. Всегда гарантируется, что вызываемая функция присваивает ему значение перед возвратом. Поэтому он будет перезаписывать значение, первоначально назначенное в любом случае.
Ответ 5
Здесь речь идет об использовании параметра параметра:
Хотя переменные, переданные как внешние аргументы, не должны быть инициализированы перед передачей, вызываемому методу требуется присвоить значение перед возвратом метода.
DateTime.TryParse
будет присвоить значение по умолчанию dt
в любом случае, и если он не может разобрать substr
, итоговый dt
будет иметь значение минимального времени datetime.
Ответ 6
DateTime.TryParse(substr, out dt);
может возвращать false, но он все равно изменит dt
. Он попытается завершить dt
в меру своих возможностей, инициализируя некоторые из значений, насколько это возможно. При использовании модификатора out
в С# вы говорите программе о его инициализации, и вы не должны ожидать сохранения значения, которое вы передаете.
Что вы можете сделать, это
DateTime dt;
if (!(DateTime.TryParse(substr, out dt))) {
using (var dtpDlgForm = new ReturnDate("Please select the Date that the file was created:")) {
if (dtpDlgForm.ShowDialog() == DialogResult.OK) {
dt = dtpDlgForm.ReturnVal;
}
else {
dt = DateTime.Now;
}
}
}
return dt;
Ответ 7
Этот код заставит предупреждение уйти. Но я думаю, что ответ Дугласа легче читать.
DateTime dt;
if (!(DateTime.TryParse(substr, out dt))) {
dt = DateTime.Now;
using (var dtpDlgForm = new ReturnDate("Please select the Date that the file was created:")) {
if (dtpDlgForm.ShowDialog() == DialogResult.OK) {
dt = dtpDlgForm.ReturnVal;
}
}
}
return dt;