Правильное время для трансляции в С#

Итак, я всегда предполагал, что кастинг и преобразование в С# в основном одно и то же: два разных способа перехода от одного типа данных к другому. Ясно, что это неверно, поскольку они часто выдают разные результаты.

Convert.ToInt32(1.6)     //outputs 2
(Int32)1.6               //outputs 1


(DateTime)("10/29/2013")          //won't compile - cannot convert type 'string' to type 'system.date.time'
Convert.ToDateTime("10/29/2013")  //outputs 10/29/2013 12:00:00 AM
  • Мой вопрос в том, что является основным различием между ними и почему они возвращают разные результаты?
  • Что такое "подходящее" время для использования одного над другим?

Лично я нахожу себя использующим метод Convert.To, который кажется мне более чистым. Я знаю, что он также выбрасывает System.InvalidCastException. Может ли кто-нибудь дать простое объяснение?

Ответ 1

Вы можете использовать приведение в двух случаях:

  • когда тип, который вы производите, является типом, который вы выполняете из
  • когда явный оператор трансляции, определенный для этих типов

Во всех остальных случаях вы должны использовать Convert или другой метод пользовательского преобразования (например, DateTime.Parse).

почему они возвращают разные результаты?

Потому что выполняется другой код. Convert.ToInt32(double value) результат округления:

int num = (int) value;
double num2 = value - num;
if ((num2 > 0.5) || ((num2 == 0.5) && ((num & 1) != 0)))    
    num++;

return num;

Ответ 2

В вашем преобразовании метод Convert.ToInt32 использует следующие правила для возвращаемого значения

округленное до ближайшего 32-разрядного целого числа со знаком. Если значение на полпути между двумя целыми числами, четное число возвращается; что равна 4,5, преобразуется в 4, а 5.5 преобразуется в 6.

Однако правила для явного преобразования отличаются

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

Если вы хотите, чтобы актер работал так же, как Convert.ToInt32 [или хотел бы указать, как будет работать округление), вы должны использовать Math.Round с литой буквой следующим образом.

(int)Math.Round(1.6) //outputs 2

Существуют другие сигнатуры методов, которые позволяют указать, как округлить.

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

Листинг-выражение формы (T) E, где T - тип, а E - унарное выражение, выполняет явное преобразование (раздел 6.2) значение E для типа T. Если явное преобразование не существует из типа от E до T, возникает ошибка времени компиляции. В противном случае результатом будет значение, полученное путем явного преобразования.

Ответ 3

Не существует быстрого правила для использования во всех случаях. Вы просто должны знать, что каждый делает, и выбрать тот, который наиболее подходит для вашего сценария. Как и вы сами указали, Convert и cast могут давать разные результаты. Причина в том, что Convert и cast могут иметь совершенно разные имптенции.

public static explicit operator MyStructA(MyStructB b)  
{
    MyStructA a = convert.ToMyStructA(b); 
    //I could do this so that convert and cast return the same but I don't have to.

    return a;
}