Различные способы преобразования типов. В чем разница - PullRequest
4 голосов
/ 25 февраля 2010

Я пытаюсь получить разницу между методами приведения типов.

например.

Метод 1

public byte fun()
{
   object value=1;
   return (byte)value; // this gives me error
}

Метод 2

public byte fun()
{
   object value=1;
   return byte.Parse(value.ToString()); // this runs 
}

Метод 3

public byte fun()
{
   object value=1;
   return Convert.ToByte(value); // this runs
}

В чем разница между всеми тремя. Как они работают внутри. Каковы тип значения и тип ссылки здесь. Какая функция может преобразовать тип значения в тип ref и наоборот

Редактировать 2

Когда я пишу эту строку, какой тип данных '1' будет обрабатываться по умолчанию int32, байтом или чем-то еще.

значение объекта = 1;

Ответы [ 3 ]

8 голосов
/ 25 февраля 2010

Здесь много вопросов.

Метод 1 не работает, потому что вы не можете выполнить распаковку и приведение в одну операцию. Вы устанавливаете "значение" в штучной упаковке целое число. Когда вы пытаетесь выполнить приведение, вы распаковываете целое число и пытаетесь преобразовать его в байт за одну операцию, что не удается. Это работает, кстати:

return (byte)( (int)value) ); // Unbox, then cast, in two operations

Метод 2 работает, потому что вы преобразуете целое число в строку, а затем используете byte.Parse для преобразования его в байт. Это очень дорого, так как он собирается в / из строк.

Метод 3 работает, потому что он видит, что объект в значении является IConvertible (int), и использует соответствующую операцию преобразования для преобразования в байт. Это, вероятно, более эффективный способ приблизиться к этому, в этом случае. Поскольку «value» хранит int, а int поддерживает IConvertible, Convert.ToByte в основном выполнит нулевую проверку, а затем вызовет Convert.ToByte (int), который довольно быстрый (он выполняет проверку границ и прямое приведение). 1008 *

Я бы рекомендовал прочитать сообщение в блоге Эрика Липперта под названием Представительство и личность . Он подробно описывает приведение и объясняет, почему метод 1 не работает ...

1 голос
/ 25 февраля 2010
// This is a direct cast. It expects that the object
// in question is already allocated as the data type
// indicated in the cast
(byte)value;

// This is a direct code conversion. It takes the argument
// and runs through code to create a new variable of the
// type byte. You'll notice if you include this in different
// code that value will still be an object but your new
// data will be a byte type
byte.Parse(value.ToString());

// This will convert any object similarly to the byte.Parse.
// It is not as fast because it does not have a definitely
// typed parameter (as parse has string). So it must go 
// through a couple of extra steps to guarantee the conversion
// is smooth.
Convert.ToByte(value);

Прямое литье всегда самое быстрое. Предполагается, что тип уже установлен и выделен, поэтому все, что ему нужно сделать, это переключить его ссылочный тип в памяти. Методы преобразования - это преобразования кода, поэтому они требуют немного больше времени. Я не знаю тестов, но Parse немного быстрее, потому что он имеет дело с определенным входом и конкретным выходом (string-> byte). Преобразование - самый медленный из методов преобразования, потому что ему не хватает той же специфичности.

0 голосов
/ 25 февраля 2010

Ну вот мой выстрел в это:

Метод 1

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

Вызов не удался, так как у компилятора нет никакой информации, из какого типа объекта он должен быть приведен, и, следовательно, он не может выполнить неявное или явное преобразование. Делая

int obj = 1;
byte b = (byte) obj; 

или

byte b = (byte) (int) obj;

работает. Второй вариант использует явную распаковку (таким образом, предоставляя необходимую информацию), как описано в комментарии и посте Рида Копси. ссылка , предоставленная комментарием Рида Копси, объясняет это подробно.

Для приведения пользовательских объектов используют неявные и явные преобразования - операторы, которые являются статическими методами, определенными в классе. Для object не существует неявных или явных операций (см. ссылка по причине), в то время как для int эти операции существуют.

Метод 2

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

Метод 3

Использует преобразование типов класса Convert. Это наиболее гибкий метод, который поддерживает большинство распространенных типов. Здесь значение должно быть преобразовано в число, а значение должно находиться в пределах байта. Класс Convert использует IConvertible для преобразования между различными типами и, следовательно, является расширяемым.

...