Преобразование литья и типа в C # [дубликат]

Просто вставляем мои два цента. Если вы хотите «ведро» списка (визуализировать слева направо), вы можете сделать следующее:

 public static List<List<T>> Buckets<T>(this List<T> source, int numberOfBuckets)
    {
        List<List<T>> result = new List<List<T>>();
        for (int i = 0; i < numberOfBuckets; i++)
        {
            result.Add(new List<T>());
        }

        int count = 0;
        while (count < source.Count())
        {
            var mod = count % numberOfBuckets;
            result[mod].Add(source[count]);
            count++;
        }
        return result;
    }
52
задан 14 March 2013 в 15:22
поделиться

9 ответов

68
ответ дан Chris 21 August 2018 в 15:11
поделиться

Кастинг не предполагает никакого преобразования, т. е. внутреннее представление значения не изменяется. Пример:

object o = "Hello"; // o is typed as object and contains a string.
string s = (string)o; // This works only if o really contains a string or null.

Вы можете преобразовать double в string, как это

double d = 5;
string s = d.ToString(); // -> "5"

// Or by specifying a format
string formatted = d.ToString("N2"); // -> "5.00"

Вы можете преобразовать string в double несколькими способами (здесь только два из них):

string s = "5";
double d = Double.Parse(s); // Throws an exception if s does not contain a valid number

Или безопасный способ

string s = "5";
double d;
if (Double.TryParse(s, out d)) {
    Console.WriteLine("OK. Result = {0}", d);
} else {
    Console.WriteLine("oops!");
}
3
ответ дан Benjamin 21 August 2018 в 15:11
поделиться
  • 1
    Convert.ToDouble() внутренне вызывает Double.Parse() . Могу ли я использовать Convert.ToDouble() по сравнению с Double.Parse() или нет и почему? – user 13 March 2013 в 21:31
  • 2
    Convert.ToDouble имеет много перегрузок, которые принимают разные типы ввода. Приёмка string перегрузки возвращает 0.0, если передана строка null. Кроме того, я не вижу возможности использовать его. – Olivier Jacot-Descombes 13 March 2013 в 21:44
  • 3
    Итак, или ... или Double.Parse() есть что предложить, что я должен рассмотреть? – user 13 March 2013 в 21:50
  • 4
    Double.Parse() является более прямым, чем Convert.ToDouble(). Если вы уверены, что ваша строка будет содержать действительное число, вы можете безопасно ее использовать, иначе я советую вам использовать Double.TryParse. – Olivier Jacot-Descombes 13 March 2013 в 21:57

Метод Convert.Double фактически просто внутренне вызывает метод Double.Parse(string).

Ни тип String, ни тип Double не определяют явное / неявное преобразование между двумя типами, поэтому литье всегда будет терпеть неудачу.

Метод Double.Parse будет смотреть на каждый символ в string и строить числовое значение, основанное на значениях символов в string. Если какой-либо из символов недействителен, метод Parse завершается с ошибкой (что также приводит к сбою метода Convert.Double).

4
ответ дан Dan 21 August 2018 в 15:11
поделиться
  • 1
  • 2
    Явное приведение не смотрит на тип данных, а просто смотрит на байты. Примером может быть листинг char x = '1' для целого числа, целое число будет 49, потому что cahracter '1' равен # 49 в таблице ascii – user1751547 13 March 2013 в 21:02
  • 3
    @ user1751547 Итак, будет ли пользователь Convert.ToDouble() смотреть за пределы байтов и рассматривать данные? – user 13 March 2013 в 21:03
  • 4
    @ user1751547 Я думаю, что это та интуиция, которая требуется для правильного ответа на этот вопрос. Просто говоря «не определено», немного спорный вопрос. – Ant P 13 March 2013 в 21:04
  • 5
    @ edmastermind29 Да, он будет смотреть на тип ввода, и если бы он был строкой, он проходил бы через каждого символа, зная, что если значение ascii char равно 49, то это символ «1» и правильно его преобразовать – user1751547 13 March 2013 в 21:06

Приведение строки в double, подобное этому, не допускается C #, поэтому вы получаете исключение, вам нужно преобразовать строку ( MSDN doc , которая показывает допустимые пути преобразования). Это просто потому, что строка не обязательно будет содержать числовые данные, но различные числовые типы (запрет нулевых значений). A Convert будет запускать метод, который проверяет строку, чтобы увидеть, можно ли ее преобразовать в числовое значение. Если это возможно, тогда оно вернет это значение. Если он не может, он выдаст исключение.

Чтобы преобразовать его, у вас есть несколько вариантов. Вы использовали метод Convert в своем вопросе, есть Parse, который во многом похож на Convert, но вы также должны посмотреть на TryParse , который позволит вам сделать:

string variable = "5.00"; 

double varDouble;

if (Double.TryParse(variable, out varDouble)) {
    //Code that runs if the conversion succeeded.
} else {
    //Code that runs if the conversion failed.
}

Это позволяет избежать возможного исключения, если вы попытаетесь выполнить Convert или Parse нечисловую строку.

1
ответ дан Keen 21 August 2018 в 15:11
поделиться
  • 1
    Могу ли я использовать TryParse над Convert, потому что TryParse проверяет, выполнено ли преобразование? – user 13 March 2013 в 21:39
  • 2
    @ edmastermind29 Я так думаю. Convert генерирует исключение, если преобразование не выполняется. TryParse вернет логическое значение, True, если преобразование выполнено успешно, а False - если оно не выполнено. – Keen 13 March 2013 в 21:44

Из MSDN :

Явные преобразования (приведения): для явных преобразований требуется оператор трансляции. Кастинг необходим, когда информация может быть потеряна при конверсии или когда преобразование может не удаться по другим причинам. Типичные примеры включают числовое преобразование в тип с меньшей точностью или меньшим диапазоном и преобразование экземпляра базового класса в производный класс.

Рассмотрим следующий пример:

double a = 2548.3;
int b;
b = (int)a; //2548 --> information (.3) lost in the conversion

А также:

Листинг - это способ явного информирования компилятора о том, что вы намерены сделать преобразование, и что вы знаете, что может произойти потеря данных.

Вы можете использовать класс System.Convert, если хотите конвертировать между несовместимыми типами. Основное различие между литьем и convert - компиляция и время выполнения . Исключения преобразования типов появляются во время выполнения, то есть при выполнении типа, который не выполняется во время выполнения, будет выведено InvalidCastException. Вывод: при кастинге вы сообщаете компилятору, что a действительно является типом b, и если это так, то проект строится без каких-либо ошибок, таких как этот пример:

double s = 2;
int a = (int) s;

Но в преобразовании вы говорите для компилятора существует способ создать новый объект из a типа b, пожалуйста, сделайте это и постройте проект без каких-либо ошибок, но, как я уже сказал, , если листинг типа не работает во время выполнения, это вызовет InvalidCastException, который должен быть брошен .

Например, код ниже никогда не компилируется, потому что компилятор обнаруживает, что не может выразить выражение типа DateTime для ввода int:

DateTime s = DateTime.Now;
int a = (int)(s);

Но этот файл скомпилирован успешно:

DateTime s = DateTime.Now;
int a = Convert.ToInt32(s);

Но во время выполнения вы получите InvalidCastException, в котором говорится:

Недопустимый литой от 'DateTime' до 'Int32'.

< / BLOCKQUOTE>
2
ответ дан S.Akbari 21 August 2018 в 15:11
поделиться

В вашем примере вы пытаетесь передать строку двойному (не целочисленному типу).

Для этого требуется явное преобразование.

И я должен указать что вы могли бы использовать Convert.ToDouble вместо Convert.ToInt64, поскольку вы можете потерять дробные части двойного значения при преобразовании в int.

, если ваша переменная имеет значение «5.25», varDouble будет иметь было 5,00 (потеря 0,25 из-за конверсии в Int64)

Чтобы ответить на вопрос о кастинге и конвертировании.

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

Посетите эту страницу MSDN для правил литья / конверсий

3
ответ дан scartag 21 August 2018 в 15:11
поделиться
  • 1
    @ edmastermind29 Я обновил свой ответ. Надеюсь, он ответит на ваш вопрос. – scartag 13 March 2013 в 21:14
  • 2
  • 3
    @ edmastermind29 Да. если значение, которое вы пытаетесь применить к числовому типу, не является числовым, приведение недействительно .. требуется преобразование. – scartag 13 March 2013 в 21:28
1
ответ дан Scott Hannen 21 August 2018 в 15:11
поделиться
10
ответ дан Servy 21 August 2018 в 15:11
поделиться
string variable = "5.00";     
double varDouble = (double)variable;

Вышеперечисление просто запрещено на языке. Ниже приведен список явных заданий для числовых типов: http://msdn.microsoft.com/en-us/library/yht2cx7b.aspx Как вы можете видеть, даже не каждый числовой тип может быть преобразован к другому численному типу

Более подробная информация о литье здесь

И как это отличается от Convert.ToDouble ()?

Когда вы создаете тип, структура данных не изменяется. Ну, в случае преобразования числовых значений вы можете потерять несколько бит или получить несколько дополнительных 0 бит. Но вы все еще работаете с номером. Вы просто меняете объем памяти, полученный этим числом. Это достаточно безопасно для компилятора, чтобы все было необходимо.

Но когда вы пытаетесь наложить строку на число, вы не можете этого сделать, потому что этого недостаточно, чтобы изменить объем памяти, взятый переменной. Например, 5.00 в виде строки представляет собой последовательность «чисел»: 53 (5) 46 (.) 48 (0) 48 (0) - это для ASCII, но строка будет содержать нечто подобное. Если компилятор просто возьмет сначала N (4 для двухзначных) байт из строки - эта часть будет содержать совершенно другой двойной номер. В то же время Convert.ToDouble () запускает специальный алгоритм, который принимает каждый символ строки, выставляет цифру, которую он представляет, и делает для вас двойной номер, если строка представляет число. Языки, подобные PHP, грубо говоря, вызовут Convert.ToDouble для вас в фоновом режиме. Но C #, как статически типизированный язык, не сделает этого для вас. Это позволяет вам быть уверенным, что любая операция безопасна по типу, и вы не получите что-то неожиданное, делая что-то вроде:

double d = (double)"zzzz"
1
ответ дан Viktor S. 21 August 2018 в 15:11
поделиться
  • 1
    @ edmastermind29 см. мой обновленный ответ. Я попытался это объяснить. Объяснение далека от совершенства, но предположим, что это объясняет разницу. – Viktor S. 13 March 2013 в 21:53
Другие вопросы по тегам:

Похожие вопросы: