Действительно ли кастинг является тем же самым как преобразованием?

Это алгоритм перетасовки knuth.

public class Knuth { 

    // this class should not be instantiated
    private Knuth() { }

    /**
     * Rearranges an array of objects in uniformly random order
     * (under the assumption that <tt>Math.random()</tt> generates independent
     * and uniformly distributed numbers between 0 and 1).
     * @param a the array to be shuffled
     */
    public static void shuffle(Object[] a) {
        int n = a.length;
        for (int i = 0; i < n; i++) {
            // choose index uniformly in [i, n-1]
            int r = i + (int) (Math.random() * (n - i));
            Object swap = a[r];
            a[r] = a[i];
            a[i] = swap;
        }
    }

    /**
     * Reads in a sequence of strings from standard input, shuffles
     * them, and prints out the results.
     */
    public static void main(String[] args) {

        // read in the data
        String[] a = StdIn.readAllStrings();

        // shuffle the array
        Knuth.shuffle(a);

        // print results.
        for (int i = 0; i < a.length; i++)
            StdOut.println(a[i]);
    }
}
41
задан Sklivvz 5 October 2008 в 22:43
поделиться

12 ответов

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

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

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

то, Когда выражение кастинга распаковывает, результат (принимающий его работает), обычно просто копия того, что было в поле с тем же типом. Существуют исключения, однако - можно распаковать от помещенного в коробку интервала до перечисления (с базовым типом интервала) и наоборот; аналогично можно распаковать от помещенного в коробку интервала до Nullable< int>.

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

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

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

Все они рассчитывают как преобразования с точки зрения спецификации - но они все не рассчитывают как преобразование объект в объект из другого типа. Я подозреваю, что это - случай Jesse Liberty, являющегося свободным с терминологией - я заметил, что в Программировании C# 3.0, который я просто читал.

, который покрывает все?

17
ответ дан Jon Skeet 23 September 2019 в 15:43
поделиться

Абсолютно нет!

Преобразовывают попытки получить Вас Int32 через "любые возможные средства". Бросок не делает ничего подобного. С броском Вы говорите компилятору рассматривать объект как Интервал без преобразования.

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

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

Попытка это

static void Main(string[] args)
{
    long l = long.MaxValue;

    Console.WriteLine(l);

    byte b = (byte) l;

    Console.WriteLine(b);

    b = Convert.ToByte(l);

    Console.WriteLine(b);

}

Результат:

9223372036854775807

255

Необработанное исключение:

Система. OverflowException: Значение больше, чем Байт. MaxValue или меньше, чем Байт. MinValue в Системе. Преобразовать. ToByte (значение Int64) [0x00000] в Test. Основной (Система. Строка [] args) [0x00019] в/home/marco/develop/test/Exceptions.cs:15

28
ответ дан Sklivvz 23 September 2019 в 15:43
поделиться

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

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 случаи.

1
ответ дан Sklivvz 23 September 2019 в 15:43
поделиться

На языке - / агностический платформой способ разговора, преобразовывающего из одного типа или класса другому, известен как [1 121] кастинг . Это верно для.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', очевидно, короток для 'броска'.

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

, Поскольку Matt говорит, различие в поведении - то, что Convert() является более явным. Вместо того, чтобы просто говорить компилятору рассматривать y как целочисленный эквивалент x, Вы конкретно говорите ему изменяться x таким способом, который подходит для целочисленного класса, тогда присваивают результат [1 110].

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

0
ответ дан Community 23 September 2019 в 15:43
поделиться

Кастинг по существу просто говорит времени выполнения "притворяться", что объект является новым типом. Это на самом деле не преобразовывает или изменяет объект всегда.

Преобразовывают, однако, выполнит операции для превращения одного типа в другого.

Как пример:

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

вывод тех операторов будет 53, потому что все время выполнения сделало посмотреть на комбинацию двоичных разрядов и рассматривать его как интервал, Что Вы заканчиваете тем, что получили, значение ASCII символа 5, а не номер 5.

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

-2
ответ дан CodeRedick 23 September 2019 в 15:43
поделиться

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

0
ответ дан Per Hornshøj-Schierbeck 23 September 2019 в 15:43
поделиться

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

-4
ответ дан Matt 23 September 2019 в 15:43
поделиться

Бросание включает Ссылки

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;

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

2
ответ дан Amy B 23 September 2019 в 15:43
поделиться

Согласно Таблице 1-7, названной "Методы для Явного Преобразования" на странице 55 в Главе 1, Урок 4 из [1 117] Рассчитанный на индивидуальную скорость обучения Учебный Набор MCTS (Экзамен 70-536): MicrosoftВ®.NET Framework 2.0— Основа Разработки приложений , существует, конечно, различие между ними.

Система. Преобразуйте , независимо от языка и преобразовывает "Между типами, которые реализуют Система. Интерфейс IConvertible ".

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

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

На раздел назвал , Как Реализовать Преобразование в Пользовательских Типах на стр 56-57 на уроке, процитированном выше, , операторы преобразования (кастинг) предназначены для упрощения преобразований между числовыми типами, тогда как Преобразовывают (), включает определенные для культуры преобразования .

то, Какую технику Вы выбираете, зависит от типа преобразования, которое Вы хотите выполнить:

  • Определяют операторы преобразования для упрощения сужения и расширения преобразований между числовыми типами.

  • Реализация Система. IConvertible для включения преобразования через Систему. Преобразовать. Используйте эту технику для включения определенных для культуры преобразований.

  • ...

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

0
ответ дан hurst 23 September 2019 в 15:43
поделиться

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

"... Истина немного более сложна, чем это..NET предоставляет три метода получения от точки для указания на B, как это было.

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

int i = 5;
double d = i;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  • Bruce Wood, 16-го ноября 2005

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

7
ответ дан thkala 23 September 2019 в 15:43
поделиться

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

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

0
ответ дан OregonGhost 23 September 2019 в 15:43
поделиться

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

На этом сайте есть хороший образец того, что выводятся для большинства методов: C # Boxing and Unboxing

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

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

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

l = i;

Явное приведение с использованием распаковки или 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: Приведение и преобразование типов

-1
ответ дан 26 November 2019 в 23:57
поделиться
Другие вопросы по тегам:

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