Коли використовувати Cast або Convert


77

Мені цікаво дізнатися, яка різниця між акторським складом, щоб сказати, intпорівняно з використанням Convert.ToInt32(). Чи є якийсь приріст продуктивності при його використанні?

Також для яких ситуацій слід використовувати кожну? В даний час я більш схильний до використання, Convertале у мене немає причин піти в будь-який бік. У думках я бачу, як вони обидва досягають однієї мети.


4
Я не погоджуюсь з тим, що моє запитання є точною копією цього питання. Це запитання задає питання, коли використовувати акторський склад або конвертувати, і прийнята відповідь нижче говорить: "Це справді питання вибору, який би ви не використовували". Моє запитання конкретно стосується різниці між кастингом та використанням Convert.To(). Тому моє запитання є доповненням до вашого запитання.

Відповіді:


39

Див. Різниця між трансляцією та конвертацією на іншому форумі

Відповідь

Convert.ToInt32(String, IFormatProvider)під називаєInt32.Parse (читайте зауваження).
Отже, єдина різниця полягає в тому, що якщо передано нульовий рядок, він повертається 0, тоді як Int32.Parseкидає ArgumentNullException.
Це справді питання вибору, яким би ви не користувались.

Особисто я не використовую ні того, ні іншого, і, як правило, використовую TryParseфункції (наприклад System.Int32.TryParse()).


ОНОВЛЕННЯ

Посилання зверху порушено, див. Цю відповідь на StackOverflow.


73
ВАЖЛИВО : Ще однією різницею, яку я нещодавно зауважив, було те, що "Cast" додає 1,63 до 1, де "Convert" перетворює 1,63 до 2. Отже, в основному конвертують раунди, а також перетворюють, але відкидають усічені значення після десяткової коми.
Abijeet Patro

Іноді TryParse недоступний.
Шон Луттін

3
Compact Framework не вистачає TryParse: stackoverflow.com/questions/22670260 / ...
Shaun Luttin

2
Тільки для посилання на коментар @AbijeetPatro, процитований з C # 5.0 у "короткому викладі" Джозефом Альбахарі та Бен Албахарі. Авторське право 2012 Джозеф Альбахарі та Бен Альбахарі, 978-1-449-32010-2. When you cast from a floating-point number to an integral, any fractional portion is truncated; no rounding is performed. The static class System.Convert provides methods that round while converting between various numeric types
Бурак Каракуш

1
Де OP сказав, що хоче перетворити рядки? Якщо варіант акторського складу - це не може бути струна.
Тім Шмельтер

78

Актори, коли це справді тип int, конвертуйте, коли це не є, intале ви хочете, щоб це стало.

Наприклад, int i = (int)o;коли ви знаєте, що o - це int

int i = Convert.ToInt32("123") оскільки "123" не є int, це рядкове представлення int.


1
Як це впливає на використання Enums?
Jonas Stawski,

12

Є ще одна різниця. "Конвертувати" завжди переповнюється, тоді як "трансляція" може бути, залежно від Ваших налаштувань та використовуваного ключового слова "перевірено" або "не перевірено".

Щоб бути більш явним. Розглянемо код:

int source = 260;
byte destination = (byte)source;

Тоді пункт призначення буде 4 без попередження.

Але:

int source = 260;
byte destination = Convert.ToByte(source);

дасть вам виняток.


6

Не всі типи підтримують перетворення, як

int i = 0;
decimal d = (decimal)i;

тому що це потрібно для реалізації явного оператора . Але .NET також забезпечує IConvertible інтерфейс , тому будь-який тип реалізує цей інтерфейс може бути перетворений на більшість вбудованих типів фреймворку. І нарешті, клас Convert допомагає оперувати типовими реалізаціями інтерфейсу IConvertible.


4

Актори просто повідомляють компілятору, що цей об’єкт насправді є реалізацією іншого типу, і поводитися з ним як з новою реалізацією зараз. Тоді як конвертор говорить, що це не успадковується від того, до чого ви намагаєтесь конвертувати, але існує певний спосіб це зробити. Наприклад, скажімо, ми перетворюємо "16" на int. "16" є рядком і жодним чином не успадковує від int. Але, очевидно, що "16" можна перетворити на int 16.


2

Вкинувши 2c - здається, що концептуальне розмежування може бути корисним. Не те, що я фахівець ..:

Кастинг змінює репрезентативний тип. Тож "32" та 32L та 32.0f здаються розумними для перекидання між собою. c # не підтримуватиме "32" автоматично, але більшість динамічних мов підтримуватимуть. Тож я буду використовувати (довгий) "32" або (String) 32L. Коли зможу. У мене також є ще одне правило - кастинг має бути з можливістю повернення.

Перетворення не повинно бути круглим шляхом, а просто може створити абсолютно новий об'єкт.

Сіра область - це, наприклад, рядок "32xx". Можна навести випадок, що коли ви його кидаєте, він стає 32 літрами (число було проаналізовано, поки цього не могло бути). Perl цим скористався. Але тоді це порушує мою вимогу туди-назад. Те саме стосується 32,5f до 32L. Майже всі мови, включаючи дуже статично набрані, дозволяють це, і це також не відповідає правилу кругового відсікання. Він сірий, оскільки якщо ви дозволяєте кидати "32", то під час компіляції ви не знаєте, чи може це бути "32xxx".

Ще одна відмінність, яку можна зробити, - це просто використовувати кастинг для "IsA", а не для "makeLookLikeA". Отже, якщо ви знаєте, що рядок походить з бази даних, але насправді це int у неофіційній схемі, сміливо використовуйте привід (хоча в цьому випадку c # хоче, щоб ви все одно використовували Convert). Те саме стосується і поплавця. Але не для того, коли ви просто використовуєте акторський склад для зрізання поплавця. Ця різниця також враховує DownCasting та UpCasting - об'єкт завжди був "IsA", але тип міг бути узагальненим для списку.


1

Існує багато перевантажень, Convert.ToInt32які можуть сприйняти, наприклад, рядок. Під час спроби перекинути рядок до int призведе до помилки компіляції. Справа в тому, що вони призначені для різних цілей. Конвертувати особливо корисно, коли ви не впевнені, якого типу є об’єкт, який ви кастуєте.


0

Є ще одна причина, чому ви повинні використовувати Convert.ToInt32 замість закидання.

Наприклад:

float a = 1.3f;
float b = 0.02f;
int c = (int)(a / b);
int d = Convert.ToInt32(a / b);`

Результат - c = 64 та d = 65


Це не через акторський склад, це правила перетворення. Якщо розділити 2 плаваючі позиції, ви отримаєте подвійне значення 64,999999068677411, під час трансляції до int це усікає лише цілу частину. Але це поверне 65: (int) (float) (a / b)), тому що в float це рівно 65, а не 64.99 (9). Те саме для десяткової. На контрасті Convert округлює результат, таким чином, тут повертається 65, але 64,49 буде 64. Смішним є те, що Intellisense каже, що приведення в плаваючу форму зайве, тоді як без нього повертається 64
Віталій

0

рядок номер = "123abc";

int num;

Int32.TryParse (число, вихідне число); // не виняток, викликаний цим викликом

Convert.ToInt32 (число); // виняток, що виникає під час цього виклику

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.