С# Casting vs. Parse

Это может показаться рудиментарным для некоторых, но этот вопрос навязывался мне, и, когда я пишу код, я решил, что попрошу.

Какое из следующего является лучшим кодом в С# и почему?

((DateTime)g[0]["MyUntypedDateField"]).ToShortDateString()

или

DateTime.Parse(g[0]["MyUntypedDateField"].ToString()).ToShortDateString()

В конечном счете, лучше ли использовать или анализировать? Спасибо всем!

Ответы

Ответ 1

Если g [0] [ "MyUntypedDateField" ] действительно является объектом DateTime, то выбор лучше всего подходит. Если это не действительно DateTime, тогда у вас нет выбора, кроме как использовать Parse (вы бы получили InvalidCastException, если попытались использовать приведение)

Ответ 2

Кастинг - это хороший .

Вы должны помнить, что результаты ToString и Parse не всегда точны - бывают случаи, когда вы не можете безопасно перемещаться между этими двумя функциями.

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

На форматирование влияют свойства текущего объекта DateTimeFormatInfo, которые по умолчанию получены из элемента "Язык и региональные стандарты" на панели управления. Одна из причин, по которой метод Parse может неожиданно выкинуть FormatException, заключается в том, что текущие свойства DateTimeFormatInfo.DateSeparator и DateTimeFormatInfo.TimeSeparator имеют одинаковое значение.

Таким образом, в зависимости от настроек пользователя код ToString/Parse может и неожиданно завершится неудачно...

Ответ 3

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

  • если вы не уверены, что эта строка может быть проанализирована, используйте DateTime.TryParse().

  • Всегда указывайте ссылку на культуру, которую вы хотите разобрать. ToShortDateString() возвращает разные выходы в разных местах. Вы почти наверняка захотите разобрать, используя ту же культуру. Я предлагаю эту функцию для обеих ситуаций;

    private DateTime ParseDateTime(object data)
    {
        if (data is DateTime)
        {
            // already a date-time.
            return (DateTime)data;
        }
        else if (data is string)
        {
            // it a local-format string.
            string dateString = (string)data;
            DateTime parseResult;
            if (DateTime.TryParse(dateString, CultureInfo.CurrentCulture,
                                  DateTimeStyles.AssumeLocal, out parseResult))
            {
                return parseResult;
            }
            else
            {
                throw new ArgumentOutOfRangeException("data", 
                                   "could not parse this datetime:" + data);
            }
        }
        else
        {
            // it neither a DateTime or a string; that a problem.
            throw new ArgumentOutOfRangeException("data", 
                                  "could not understand data of this type");
        }
    }
    

Затем назовите это:

ParseDateTime(g[0]["MyUntypedDateField").ToShortDateString();

Обратите внимание, что неверные данные вызывают исключение, поэтому вы хотите поймать это.

Также; оператор 'as' не работает с типом данных DateTime, так как это работает только со ссылочными типами, а DateTime - тип значения.

Ответ 4

Поскольку @Brian R. Bondy указал, что это зависит от реализации g [0] [ "MyUntypedDateField" ]. Безопасная практика заключается в использовании DateTime.TryParse и как.

Ответ 5

Parse требует строку для ввода, для кастинга требуется объект, поэтому во втором примере, который вы указали выше, вам необходимо выполнить две приведения: одну из объекта в строку, а затем из строки в DateTime. Первый - нет.

Однако, если при выполнении броска существует риск исключения, тогда вам может понадобиться пройти второй маршрут, чтобы вы могли TryParse и избегать дорогого исключения. В противном случае пройдите самый эффективный маршрут и просто отбросьте один раз (от объекта к DateTime), а не дважды (от объекта к строке до DateTime).