разница между (int) объектом и int.parse (object.ToString ()) [duplicate]

В веб-приложении каждая задача выполняется в виде запроса и ответа.

Программирование на стороне клиента - это HTML-код с Java-скриптом и его фреймворками, библиотеки выполняются в Internet Explorer, Mozilla, Chrome-браузерах. В сценарии Java-сценария серверные сервлеты программирования выполняются в Tomcat, web-логике, j боссе, WebSphere severs

40
задан Sklivvz 5 October 2008 в 12:43
поделиться

11 ответов

Простой ответ: это зависит.

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

float f = 1.5f;
int i = (int) f; // Conversion

Когда выражение литья распаковывается, результат (при условии, что он работает) является обычно просто копией того, что было в поле, с тем же типом. Однако есть исключения - вы можете распаковать из вложенного int в enum (с базовым типом int) и наоборот; Аналогично, вы можете распаковать из вложенного пакета int в Nullable & lt; int & gt;.

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

object o = "hello";
string x = (string) o; // No data is "converted"; x and o refer to the same object

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

Все из них считаются конверсиями в терминах спецификации, но они не все считают преобразованием объекта в объект другого типа. Я подозреваю, что это случай, когда Джесси Либерти расходилась с терминологией. Я заметил это в Программе C # 3.0, которую я только что читал.

Все это покрывает?

16
ответ дан Jon Skeet 28 August 2018 в 05:08
поделиться
  • 1
    Я думаю, вы имели в виду int i = (int) f; в первом блоке кода. – JacquesB 27 September 2008 в 19:33
  • 2
    очень важно то, что если вы работаете со строковыми сохраненными номерами, это то, что (int) & quot; & quot; = сбой, в то время как Convert.ToInt32 (& quot;) = 0, а также длинное десятичное значение в строке не будет правильно преобразовываться для культуры и сбоя при произведении, но будет отлично работать с Convert.ToDecimal () – Franck 4 March 2014 в 14:49

Кастинг включает ссылки

List<int> myList = new List<int>();
//up-cast
IEnumerable<int> myEnumerable = (IEnumerable<int>) myList;
//down-cast
List<int> myOtherList = (List<int>) myEnumerable;

Обратите внимание, что операции с myList, такие как добавление элемента, отражаются в myEnumerable и myOtherList. Это связано с тем, что все эти ссылки (разных типов) относятся к одному и тому же экземпляру.

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

Преобразование включает экземпляры

List<int> myList = new List<int>();
int[] myArray = myList.ToArray();

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

decimal w = 1.1m;
int x = (int)w;

Существуют операции с использованием синтаксиса cast в C #, которые фактически являются преобразованиями .

2
ответ дан Amy B 28 August 2018 в 05:08
поделиться
  • 1
    Не совсем ... вы не можете изменить тип ссылки или тип экземпляра. Вы получаете NEW-ссылку другого типа на один и тот же объект и получаете новый объект или структуру другого типа. – Sklivvz 27 September 2008 в 18:54
  • 2
    Отредактировано, этот ответ лучше? – Amy B 27 September 2008 в 21:06

Кастинг по существу просто говорит во время выполнения «притворяться», что объект является новым типом. Он фактически не конвертирует или не изменяет объект.

Convert, однако, будет выполнять операции, чтобы превратить один тип в другой.

В качестве примера:

char caster = '5';
Console.WriteLine((int)caster);

Выход этих операторов будет 53, потому что все время выполнения - это просмотр битового шаблона и рассмотрение его как int. То, что вы получаете, это значение ascii символа 5, а не число 5.

Если вы используете Convert.ToInt32 (caster), однако вы получите 5, потому что он действительно читает строку и модифицирует это правильно. (По сути, он знает, что значение 53 ASCII действительно является целым значением 5.)

-2
ответ дан CodeRedick 28 August 2018 в 05:08
поделиться
  • 1
    Не огромная разница, но она все равно обновилась. ;) Пример по-прежнему работает независимо от времени выполнения или компилятора, и я думаю, что в любом случае получается реальная точка ... – CodeRedick 27 September 2008 в 18:34
  • 2
    Примечание для себя: используйте вырезать / вставить, а не печатать в миниатюрном окне редактора. Спасибо, что указали на ошибку! – CodeRedick 27 September 2008 в 19:19

В языке / структуре-агностическом образе речи преобразование из одного типа или класса в другое известно как литье. Это верно и для .NET, так как ваши первые четыре строки показывают:

object x;
int y;

x = 4;

y = ( int )x;

Языки C и C (например, C #) используют синтаксис (newtype)somevar для кастинга. В VB.NET, например, для этого существуют явные встроенные функции. Последняя строка будет записана как:

y = CInt(x)

Или для более сложных типов:

y = CType(x, newtype)

Где «C» явно не подходит для «cast».

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

Как говорит Мэтт , разница в поведении заключается в том, что Convert() более явственно. Вместо того, чтобы просто сообщать компилятору относиться к y как целочисленный эквивалент x, вы специально говорите ему об изменении x таким образом, который подходит для целочисленного класса, , затем присвойте результат y.

В вашем конкретном случае кастинг делает то, что называется «unboxing», тогда как Convert() фактически получит целочисленное значение. Результат будет таким же, но есть тонкие отличия лучше , объясненные Keith .

0
ответ дан Community 28 August 2018 в 05:08
поделиться

В соответствии с таблицей 1-7, озаглавленной «Методы явного преобразования» на стр. 55 в главе 1, Урок 4 набора для самостоятельного обучения MCTS (экзамен 70-536): Microsoft® .NET Framework 2.0-Application Development Foundation, существует определенная разница между ними.

System.Convert не зависит от языка и преобразует «Между типами, реализующими интерфейс System.IConvertible

(тип) - это спецификация языка C #, которая преобразует «Между типами, которые определяют операторы преобразования ».

Кроме того, при реализации пользовательских преобразований между ними существуют разные советы.

В разделе «Реализация преобразования в пользовательских типах» на стр. 56-57 в уроке, приведенном выше, операторы преобразования (литье) предназначены для упрощения конверсий между числовыми типами, тогда как Convert () (/ g10)

Какой метод вы выбираете, зависит от типа преобразования, которое вы хотите form:

  • Определить операторы преобразования, чтобы упростить сужение и расширение конверсий между числовыми типами.
  • Внедрить System.ICконвертируемый, чтобы включить преобразование через System.Convert. Используйте этот метод, чтобы включить конверсии, специфичные для культуры.
  • ...

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

0
ответ дан hurst 28 August 2018 в 05:08
поделиться

Разница в том, является ли преобразование неявным или явным. Первый - это бросок, второй - более явный вызов функции, которая преобразуется. Они, вероятно, продолжают делать то же самое по-разному.

-4
ответ дан Matt 28 August 2018 в 05:08
поделиться

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

На этом сайте есть хороший пример того, какие результаты для большинства из методов: C # Бокс и Unboxing

Итак, учитывая эти выборочные переменные:

int i = 3, x;
long l;
string s = "5";

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

l = i;

Явное кастинг с использованием unboxing или ключевое слово as:

s = (string)i;
//or
s = i as string;

Явные преобразования с использованием методов из System.Convert:

i = System.Convert.ToInt32(s);

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

i = int.Parse(s);
i = int.TryParse(s, x);

Явные преобразования с использованием методов из экземпляра переменной:

s = i.ToString();

Я считаю, что кастинг - это просто способ присвоения между два совместимых типа.

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

Некоторая хорошая информация также о MSDN: Кастинг и конвертация типов ионы [/ д2]

0
ответ дан Mxyzptlk 28 August 2018 в 05:08
поделиться

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

Термин «преобразование» иногда используется для кастинга, но обычно это делается с помощью какой-либо библиотеки или вашего собственного кода и необязательно приводят к тому же, что и к литье. Например, если у вас есть значение имперского веса и преобразовать его в метрический вес, он может оставаться одним и тем же типом данных (скажем, float), но становится другим числом. Другим типичным примером является преобразование из градусов в радиан.

0
ответ дан OregonGhost 28 August 2018 в 05:08
поделиться
  • 1
    Мне нравится ваш ответ, но я не знаю, является ли «тип данных» лучшим способом его описания. – mattlant 27 September 2008 в 18:12
  • 2
    Тип данных - это слово, которое я узнал для этого. Не стесняйтесь предлагать лучшее слово :) – OregonGhost 27 September 2008 в 18:17
  • 3
    если мы говорим строго примитивно, это подходит, но когда вы попадаете в классные классы, он больше не подходит. Хм, я не знаю, кроме просто «типа» :) – mattlant 27 September 2008 в 18:21
  • 4
    Кастинг ссылочного типа, конечно, не изменяет тип самого объекта. Он изменяет эффективный тип reference . – Jon Skeet 27 September 2008 в 18:22
  • 5
    Если вы производите явный или неявный оператор кастинга, который возвращает другой тип, это изменение не обязательно только в ссылке, потому что вы можете получить новый объект. С другой стороны, это то, что я имел в виду с «переинтерпретированием бит», хотя я не говорил о типах ссылок. – OregonGhost 27 September 2008 в 20:35

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

0
ответ дан Per Hornshøj-Schierbeck 28 August 2018 в 05:08
поделиться
  • 1
    Кроме того, есть очевидные случаи, когда литой объект НЕ относится к типу, которому подчиняются: double d = 3.14159; int i = (int) d; Двойной не является int; и ни один из них не является двойным. Между ними существует только определенный листинг. – Jacob Krall 27 September 2008 в 18:37

Семантика в сторону, быстрый тест показывает, что они НЕ эквивалентны! Они выполняют задачу по-другому (или, возможно, выполняют разные задачи).

x=-2.5 (int)x=-2 Convert.ToInt32(x)=-2
x=-1.5 (int)x=-1 Convert.ToInt32(x)=-2
x=-0.5 (int)x= 0 Convert.ToInt32(x)= 0
x= 0.5 (int)x= 0 Convert.ToInt32(x)= 0
x= 1.5 (int)x= 1 Convert.ToInt32(x)= 2
x= 2.5 (int)x= 2 Convert.ToInt32(x)= 2

Обратите внимание на x=-1.5 и x=1.5.

28
ответ дан Sklivvz 28 August 2018 в 05:08
поделиться

Лучшее объяснение, которое я видел, можно увидеть ниже, за которым следует ссылка на источник:

"... Правда немного сложнее, чем это. .NET предоставляет три метода получить от точки А до точки В. Как бы это было.

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

int i = 5;
double d = i;

Они также называются «расширяющимися конверсиями», а .NET позволяет выполнять их без какого-либо оператора трансляции, потому что вы никогда не сможете потерять какую-либо информацию: допустимый диапазон допустимых значений двойника охватывает диапазон действительных значений значения для int, а затем некоторые, поэтому вы никогда не станете выполнять это задание, а затем обнаружите свой ужас, что среда выполнения потеряла несколько цифр от вашего значения int. Для ссылочных типов правило, лежащее в основе неявного литья, заключается в том, что приведение никогда не может вызвать InvalidCastException: для компилятора ясно, что листинг всегда действителен.

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

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

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

double d = 1.5;
int i = (int)d;

Здесь вы, очевидно, потеряете информацию : Я буду 1 после броска, поэтому 0.5 потеряется. Это также называется «сужающимся» преобразованием, и компилятор требует, чтобы вы включили явное выражение (int), чтобы указать, что да, вы знаете, что информация может быть потеряна, но вам все равно.

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

Третий вид преобразования - это тот, который включает в себя такое радикальное изменение представления, что дизайнеры не предоставили даже явного приведения: они заставляют вас вызывать метод для преобразования:

string s = "15";
int i = Convert.ToInt32(s);

Обратите внимание, что нет ничего, что абсолютно требует вызова метода здесь. Неявные и явные приведения - это вызовы методов (так вы сами делаете). Дизайнеры вполне могли создать явный оператор литья, который преобразовал строку в int. Требование, которое вы называете методом, является стилистическим выбором, а не фундаментальным требованием к языку.

Стилистическая аргументация выглядит примерно так: String-to-int - это сложное преобразование с большим количеством возможностей для вещей ужасно ошибочно:

string s = "The quick brown fox";
int i = Convert.ToInt32(s);

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

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

  • Брюс Вуд, 16 ноября 2005 г.

http://bytes.com/forum/post1068532-4.html

7
ответ дан thkala 28 August 2018 в 05:08
поделиться
  • 1
    Следует отметить, что литье длинного до двойного считается "расширяющимся" несмотря на то, что это преобразование из «точного значения», тип, который может привести к тому, что новая переменная не будет иметь такое же значение, как и старое. К сожалению, несмотря на решение Microsoft использовать синглы для аргументов многих графических функций и, несмотря на то, что двойной по сути является «приблизительным значением», тип, Microsoft считает, что двойное преобразование с относительно низким уровнем потерь и «сужение». – supercat 2 February 2011 в 07:18
Другие вопросы по тегам:

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