Разница между приведением типов и использованием метода Convert.To ()

89

У меня есть функция , которая проливает doubleна stringзначениях.

string variable = "5.00"; 

double varDouble = (double)variable;

Было зарегистрировано изменение кода, и проект строится с ошибкой: System.InvalidCastException: Specified cast is not valid.

Однако после выполнения следующих действий ...

string variable = "5.00"; 

double varDouble = Convert.ToDouble(variable);

... проект строится без ошибок.

В чем разница между кастингом и использованием Convert.To()метода? Почему кастинг бросает, Exceptionа использование - Convert.To()нет?


источник
6
Что касается упомянутого вопроса , OP спрашивает, когда использовать приведение или преобразование, и принятый ответ гласит: «Это действительно вопрос выбора, какой бы вы ни использовали». Я спрашиваю разницу между актерским составом и новообращенным. На мой взгляд, ответы ниже (слава SO!) Предоставляют более подробную информацию о различиях по сравнению с «использованием того или иного по выбору» ... и эта деталь, по сути, может быть использована для более осознанного выбора.
@ edmastermind29 нет большой разницы между «в чем разница между x и y» и «когда использовать x и y» в контексте программирования. Оба взаимно отвечают друг другу.
nawfal
2
Спустя почти 3 года, похоже, что в этом случае никто не отвечает друг другу. Q: «В чем разница между X и Y?» A: «Это действительно вопрос выбора, что бы вы ни использовали». Не очень полезно.
Похоже, что ни у кого нет прямого ответа на вопрос, какой вариант лучше всего работает, также является частью вопроса. По моему опыту я вижу, что Cast лучше, особенно при получении таких значений столбцов, как это .. (int) datatable.Rows [0] [0], если мы знаем его 100% int
Сундара

Ответы:

126

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

Приведение - это действие по изменению объекта одного типа данных на другой.

Это немного общий характер и в какой-то мере эквивалентен преобразованию, потому что приведение часто имеет тот же синтаксис преобразования, поэтому вопрос должен заключаться в том, когда преобразование (неявное или явное) разрешено языком и когда вам нужно использовать ( подробнее) явное преобразование?

Позвольте мне сначала провести простую линию между ними. Формально (даже если это эквивалентно синтаксису языка) преобразование изменит тип, в то время как преобразование изменит / может изменить значение (в конечном итоге вместе с типом). Также приведение обратимо, а преобразование - нет.

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

Неявные приведения

В C # приведение неявно, если вы не потеряете никакой информации (обратите внимание, что эта проверка выполняется с типами, а не с их фактическими значениями ).

Примитивные типы

Например:

int tinyInteger = 10;
long bigInteger = tinyInteger;

float tinyReal = 10.0f;
double bigReal = tinyReal;

Эти приведения являются неявными, потому что во время преобразования вы не потеряете никакой информации (вы просто сделаете тип шире). И наоборот, неявное приведение типов недопустимо, потому что, независимо от их фактических значений (потому что они могут быть проверены только во время выполнения), во время преобразования вы можете потерять некоторую информацию. Например, этот код не будет компилироваться, потому что a doubleможет содержать (и фактически содержит) значение, не представимое с помощью float:

// won't compile!
double bigReal = Double.MaxValue;
float tinyReal = bigReal;

Объекты

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

string text = "123";
IFormattable formattable = text;

NotSupportedException derivedException = new NotSupportedException();
Exception baseException = derivedException;

В этом случае компилятор знает, что stringреализует IFormattableи что NotSupportedExceptionявляется (производным), Exceptionпоэтому приведение является неявным. Никакая информация не теряется, потому что объекты не меняют свои типы (это отличается от structs и примитивных типов, потому что с приведением вы создаете новый объект другого типа ), какие изменения - это ваше представление о них.

Явные приведения

Приведение является явным, когда преобразование не выполняется неявно компилятором, а затем необходимо использовать оператор приведения. Обычно это означает, что:

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

Примитивные типы

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

double precise = Math.Cos(Math.PI * 1.23456) / Math.Sin(1.23456);
float coarse = (float)precise;

float epsilon = (float)Double.Epsilon;

В обоих примерах, даже если значения попадают в floatдиапазон, вы потеряете информацию (в данном случае точность), поэтому преобразование должно быть явным. А теперь попробуйте это:

float max = (float)Double.MaxValue;

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

// won't compile!
string text = "123";
double value = (double)text;

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

Объекты

Преобразования из указателей (в объекты) могут завершиться ошибкой, если типы не связаны, например, этот код не будет компилироваться (потому что компилятор знает, что возможное преобразование невозможно):

// won't compile!    
string text = (string)AppDomain.Current;
Exception exception = (Exception)"abc";

Этот код будет компилироваться, но может завершиться ошибкой во время выполнения (это зависит от эффективного типа приведенных объектов) с InvalidCastException:

object obj = GetNextObjectFromInput();
string text = (string)obj;

obj = GetNextObjectFromInput();
Exception exception = (Exception)obj;

Конверсии

Итак, наконец, если приведение является преобразованием, тогда зачем нам нужны классы вроде Convert? Игнорирование тонких различий, связанных с Convertреализацией и IConvertibleреализациями на самом деле, потому что в C # с приведением вы говорите компилятору:

поверьте мне, этот тип - тот тип, даже если вы не можете этого знать сейчас, позвольте мне сделать это, и вы увидите.

-или-

не волнуйтесь, меня не волнует, что при этом преобразовании что-то будет потеряно.

Для всего остального требуется более явная операция (подумайте о последствиях простых приведений , поэтому C ++ ввел для них длинный, подробный и явный синтаксис). Это может потребовать сложной операции (для string-> doubleпреобразования потребуется синтаксический анализ). Преобразование string, например, в всегда возможно (с помощью ToString()метода), но оно может означать нечто иное, чем вы ожидаете, поэтому оно должно быть более явным, чем приведение (чем больше вы пишете, тем больше думаете о том, что делаете ).

Это преобразование может быть выполнено внутри объекта (используя для этого известные инструкции IL), используя пользовательские операторы преобразования (определенные в классе для приведения) или более сложные механизмы ( TypeConverterнапример, методы или методы класса). Вы не знаете, что произойдет с этим, но вы знаете, что это может потерпеть неудачу (поэтому IMO, когда возможно более контролируемое преобразование, вы должны его использовать). В вашем случае преобразование просто проанализирует, stringчтобы создать double:

double value = Double.Parse(aStringVariable);

Конечно, это может потерпеть неудачу, поэтому, если вы это сделаете, вы всегда должны перехватить исключение, которое оно может выбросить ( FormatException). Здесь это не по теме, но когда TryParseдоступен, вы должны использовать его (потому что семантически вы говорите, что это может быть не число, и это еще быстрее ... потерпеть неудачу).

Конверсии в .NET могут происходить из множества мест, TypeConverterнеявных / явных приведений с определенными пользователем операторами преобразования, реализации IConvertibleи методов анализа (я что-то забыл?). Загляните в MSDN, чтобы узнать о них подробнее.

Чтобы закончить этот длинный ответ, несколько слов об определяемых пользователем операторах преобразования. Это просто сахар, позволяющий программисту использовать приведение для преобразования одного типа в другой. Это метод внутри класса (тот, который будет приведен), который говорит: «Эй, если он / она хочет преобразовать этот тип в этот тип, я могу это сделать». Например:

float? maybe = 10; // Equals to Nullable<float> maybe = 10;
float sure1 = (float)maybe; // With cast
float sure2 = maybe.Value; // Without cast

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

EasyString text = "123"; // Implicit from string
double value = (string)text; // Explicit to double

В своей реализации вы можете решить «облегчить жизнь программисту» и раскрыть это преобразование через приведение (помните, что это просто ярлык, чтобы писать меньше). Некоторые языки могут даже допускать это:

double value = "123";

Разрешение неявного преобразования в любой тип (проверка будет выполняться во время выполнения). С соответствующими параметрами это можно сделать, например, в VB.NET. Это просто другая философия.

Что мне с ними делать?

Итак, последний вопрос: когда использовать тот или иной? Посмотрим, когда можно использовать явное приведение:

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

Может быть выполнено только первое преобразование, Convertпоэтому для остальных у вас нет выбора, и вам нужно использовать явное приведение.

Теперь посмотрим, когда можно будет использовать Convert:

  • Преобразования из любого базового типа в другой базовый тип (с некоторыми ограничениями, см. MSDN ).
  • Преобразования из любого типа, который реализуется, IConvertibleв любой другой (поддерживаемый) тип.
  • Преобразования из / в byteмассив в / из строки.

Выводы

IMO Convertследует использовать каждый раз, когда вы знаете, что преобразование может завершиться неудачно (из-за формата, из-за диапазона или из-за того, что оно может быть неподдерживаемым), даже если такое же преобразование может быть выполнено с преобразованием (если не доступно что-то еще). Он дает понять, кто будет читать ваш код, каковы ваши намерения и что он может потерпеть неудачу (упрощая отладку).

Для всего остального вам нужно использовать приведение, выбора нет, но если доступен другой лучший метод, я предлагаю вам использовать его. В вашем примере преобразование из stringв double- это то, что (особенно если текст поступает от пользователя) очень часто терпит неудачу, поэтому вы должны сделать его как можно более явным (более того, вы получите больше контроля над ним), например, используя TryParseметод.

Изменить: в чем разница между ними?

Согласно обновленному вопросу и сохранению того, что я написал ранее (о том, когда вы можете использовать приведение по сравнению с тем, когда вы можете / должны использовать Convert), последний момент, который нужно уточнить, - есть ли разница между ними (кроме того, Convertиспользует IConvertibleи IFormattableинтерфейсы, чтобы он мог выполнять операции не допускается с приведениями).

Короткий ответ - да, они по-разному ведут себя . Я вижу этот Convertкласс как класс вспомогательных методов, поэтому часто он дает некоторые преимущества или немного другое поведение. Например:

double real = 1.6;
int castedInteger = (int)real; // 1
int convertedInteger = Convert.ToInt32(real); // 2

Совсем другое дело, правда? Приведение обрезается (это то, что мы все ожидаем), но Convertвыполняет округление до ближайшего целого числа (чего нельзя ожидать, если вы этого не знаете). Каждый метод преобразования имеет различия, поэтому общее правило не может применяться, и их нужно рассматривать в каждом конкретном случае ... 19 базовых типов для преобразования в любой другой тип ... список может быть довольно длинным, гораздо лучше проконсультироваться с случаем MSDN, кейс!

Адриано Репетти
источник
Я изменил вопрос, чтобы задать Difference between casting and using the Convert.To() method. В противном случае очень исчерпывающий ответ. (Надеюсь, мой вопрос
@ edmastermind29 Я немного отредактировал вопрос, тема слишком длинная даже для длинного ответа (300+ возможных преобразований в список). Convert добавляет преимущества (или просто неожиданное поведение?) Не только по сравнению с приведением типов, но и с "простыми" интерфейсами IConvertible и IFormattable.
Адриано Репетти
Мне не нравится заимствованное из языка C представление о том, что doubleзначения, не представляющие целые числа, должны быть «конвертируемы» int. Приведение могло бы показаться подходящей парадигмой в тех случаях, когда, например, извлекаются Int32значения из a, double[]который содержит смесь реальных чисел и Int32значений, которые были преобразованы в double[попытка преобразовать значение, которое невозможно точно представить в, int32будет указывать на неожиданное состояние и должен вызывать исключение], но я бы подумал, что когда кто-то хочет преобразование с потерями, нужно конкретизировать желаемую форму.
supercat
1
Другое отличие - от объектных к примитивным типам. egobject o = 123; var l = Convert.ToInt64(o); var i = (long) (int) o; var f = (long) o // InvalidCastException
yue shi
1
@ rory.ap это важный момент. Нет, формально это не приведение ( float-> int), а принуждение . Например, приведение может быть DerivedClass-> BaseClass. Это сбивает с толку, потому что в C # мы используем одно и то же слово (и оператор) для обоих, но на самом деле это разные вещи. Формальное определение для их различения немного сложнее, чем то, что я написал.
Адриано Репетти,
12

Приведение - это способ сказать компилятору: «Я знаю, что вы думаете, что эта переменная - это Bar, но я знаю больше, чем вы; объект на самом деле является Foo, поэтому позвольте мне рассматривать его, как если бы это был Foo из сейчас на." Затем во время выполнения, если фактический объект оказался действительно Foo, тогда ваш код работает, если окажется, что объект вообще не был Foo, вы получите исключение. (В частности, ан System.InvalidCastException.)

С другой стороны, преобразование - это способ сказать: «Если вы дадите мне объект типа Bar, я могу создать новый объект Foo, который представляет то, что находится в этом объекте Bar. Я не буду менять исходный объект, он выиграл» Если относиться к исходному объекту по-другому, он создаст что-то новое, основанное только на каком-то другом значении . Что касается того, как он будет это делать, это может быть что угодно. В этом случае Convert.ToDoubleон вызоветDouble.Parseкоторый имеет всевозможную сложную логику для определения того, какие типы строк представляют какие числовые значения. Вы можете написать свой собственный метод преобразования, который по-разному сопоставлял строки с двойниками (возможно, для поддержки совершенно другого соглашения об отображении чисел, таких как римские цифры или что-то еще). Преобразование может делать что угодно, но идея в том, что на самом деле вы не просите компилятор что-либо делать за вас; вы пишете код, чтобы определить, как создать новый объект, потому что компилятор без вашей помощи не знает, как сопоставить (например) a stringс a double.

Итак, когда вы конвертируете, а когда кастуете? В обоих случаях у нас есть некоторая переменная типа, скажем, A, и мы хотим иметь переменную типа B. Если наш объект A действительно, на самом деле, скрытый под капотом, является B, тогда мы приводим. Если на самом деле это не B, то нам нужно преобразовать его и определить, как программа должна получать B от A.

Сервировка
источник
В одном из сообщений SO Эрик Липперт упомянул, что не существует такой вещи, как неявное приведение, и что это неявное преобразование . Я использовал трансляцию и преобразование как взаимозаменяемые. что не так в словах "неявное приведение"? Разве, если преобразование является неявным, не требуя приведения, можно сказать, что это «неявное приведение»?
rahulaga_dev
1
@RahulAgarwal Приведение представляет собой операцию, в которой вам необходимо явно указать, что данный тип является (или может быть преобразован) в допустимый экземпляр другого типа. Когда существует неявное преобразование, для обработки типа как другого типа приведение не требуется . Поэтому выражение «неявное приведение» на самом деле не имеет смысла (за исключением потенциально нескольких ситуаций, подобных упомянутому Эриком, когда оператор приведения добавляется без его ввода разработчиком, как при использовании a foreach). За исключением этих исключений приведение типов по определению является явным.
Servy
5

Откуда MSDN:

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

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

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

А также:

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

Вы можете использовать System.Convertclass, когда хотите конвертировать между несовместимыми типами. Основное различие между литьем и обращенным в компиляции и время выполнения . Исключения преобразования типа появляются во время выполнения , т. Е. Приведение типа, которое завершается неудачно во время выполнения, вызовет 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.

Салах Акбари
источник
4

На Convert.Doubleсамом деле метод просто вызывает Double.Parse(string)метод внутри себя .

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

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

Дэн
источник
1
И чем это отличается от явного приведения?
3
Явное приведение не смотрит на тип данных, оно просто смотрит на байты. Примером может быть приведение char x = '1' к целому числу, целое число будет 49, потому что символ '1' находится под номером 49 в таблице ascii
user1751547
@ user1751547 Итак, сможет ли пользователь Convert.ToDouble()выйти за рамки байтов и рассмотреть данные?
@ user1751547 Я думаю, что для правильного ответа на этот вопрос требуется такая интуиция. Просто говоря «это не определено» немного спорно.
Ant P
@ edmastermind29 Да, он будет смотреть на тип ввода, и если бы это была строка, он проходил бы через каждый символ, зная, что если значение ascii для char было 49, то это символ '1' и правильно его преобразовал
user1751547
3

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

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

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

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

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

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

Посетите эту страницу MSDN, чтобы узнать правила трансляции / преобразования

скартаг
источник
@ edmastermind29, я обновил свой ответ. Надеюсь, он ответит на ваш вопрос.
scartag
Каковы требования для явного приведения ... в связи с моим вопросом? Что касается «нецелочисленной» стоимости?
@ edmastermind29 Да. если значение, которое вы пытаетесь преобразовать в числовой тип, не является числовым, преобразование недопустимо. требуется преобразование.
scartag
3

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

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.

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

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

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

Вы можете преобразовать a stringв a 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!");
}
Оливье Жако-Декомб
источник
Convert.ToDouble()внутренние звонкиDouble.Parse() . В моих интересах использовать Convert.ToDouble()over Double.Parse()или нет и почему?
Convert.ToDoubleимеет много перегрузок, которые принимают разные типы ввода. Принятие перегрузки stringвозвращается, 0.0если nullпередана строка. Кроме того, я не вижу преимуществ в его использовании.
Olivier Jacot-Descombes,
Итак, либо, либо ... или Double.Parse()мне есть что предложить?
Double.Parse()прям чем Convert.ToDouble(). Если вы уверены, что ваша строка будет содержать действительный номер, вы можете смело использовать его, в противном случае я советую вам использовать Double.TryParse.
Olivier Jacot-Descombes
1
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"
Виктор С.
источник
@ edmastermind29 см. мой обновленный ответ. Я пытался это объяснить. Объяснение далеко от совершенства, но предположим, что оно объясняет разницу.
Виктор С.
1

Преобразование строки в двойное значение запрещено C #, поэтому вы получаете исключение, вам необходимо преобразовать строку ( документ MSDN, в котором показаны допустимые пути преобразования). Это просто потому, что строка не обязательно будет содержать числовые данные, но различные числовые типы будут (за исключением нулевых значений). 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нечисловая строкой.

Острый
источник
В моих интересах использовать TryParseовер, Convertпотому что TryParseпроверяет успешность преобразования?
@ edmastermind29 Думаю, что да. Convert выдаст исключение, если преобразование завершится неудачно. TryParse вернет логическое значение True, если преобразование выполнено успешно, и False, если оно не выполнено.
Keen
1

double varDouble = (double)variableпредполагает, что variableэто уже дубль. Если variableэто не двойник (это строка), тогда это не удастся. double varDouble = Convert.ToDouble(variable)неужели как говорится - конвертирует. Если он может проанализировать или иным образом извлечь из variableнего двойник, он это сделает.

Я использую Double.Parseили Double.TryParseпотому что он более четко указывает на то, что должно происходить. Вы начинаете со строки и ожидаете, что она будет преобразована в двойную. Если есть сомнения, используйте TryParse.

Если variableэто аргумент метода, измените тип на double. Сделайте вызывающего ответственным за предоставление правильного типа. Таким образом, компилятор сделает всю работу за вас.

Скотт Ханнен
источник
-1

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

TomHardy
источник