Типизация в С#

Что такое литье типов, в чем его польза? Как это работает?

Ответ 1

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

object x = "hello";

...

// I know that x really refers to a string
string y = (string) x;

Существуют различные операторы преобразования. Форма (typename) expression может выполнять три разные вещи:

  • Преобразование unboxing (например, от целого числа в блоке до int)
  • Пользовательское преобразование (например, литье XAttribute в string)
  • Референсное преобразование в иерархии типов (например, отбрасывание object до string)

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

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

object x = new object();
string y = x as string; // Now y is null because x isn't a string

Его можно использовать для unboxing для типа значения NULL:

object x = 10; // Boxed int
float? y = x as float?; // Now y has a null value because x isn't a boxed float

Существуют также неявные преобразования, например. от int до long:

int x = 10;
long y = x; // Implicit conversion

Оказывает ли это все, что вас интересует?

Ответ 2

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

Приведение к базовому типу:

string greeting = "Hi Bob";
object o = greeting;

Это создает более общую ссылку (объект) из более конкретной ссылки (строки). Возможно, вы написали код, который может обрабатывать любой объект, например:

Console.WriteLine("Type of o is " + o.GetType());

Этот код не нужно изменять независимо от того, какие объекты вы задали o.

понижающее приведение:

object o = "Hi Bob";
string greeting = (string)o;

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

if (o is string)
{ do something }

Теперь вы можете рассматривать ссылку как строку вместо объекта. Например. строка имеет длину (но объект не работает), поэтому вы можете сказать:

Console.WriteLine("Length of string is " + greeting.length);

Что вы не можете сделать с объектом.

Ответ 3

См. this или this:

Поскольку С# статически типизируется во время компиляции, после объявления переменной, он не может быть объявлен повторно или используется для хранения значений другого типа, если только этот тип не конвертируется в тип переменной

...

Однако иногда вам может понадобиться скопировать значение в переменную или параметр метода другого типа. Например, у вас может быть целочисленная переменная, которую нужно передать методу, параметр которого указан как двойной. Или вам может потребоваться присвоить переменную класса переменной типа интерфейса. Эти виды операций называются преобразованиями типов. В С# вы можете выполнять следующие виды конверсий.

Ответ 4

Отключение от одного типа данных к другому.

Для общего чтения см. this.

См. также msdn

Ответ 5

Кроме того, если вы явно выполняете кастинг, вы можете воспользоваться сочетанием шаблонов. Если у вас есть объект:

object aObject = "My string value";

Вы можете безопасно отбросить объект в виде строки в одной строке:

if (aObject is string aString)
{
    Console.WriteLine("aString = " + aString)
    // Output: "aString = My string value"
}

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

public void Conversion(object objA, object objB)
{
    // Fail out early if the objects provided are not the correct type, or are null
    if (!(objA is string str) || !(objB is int num)) { return; }

    // Now, you have `str` and `num` that are safely cast, non-null variables
    // all while maintaining the same scope as your Conversion method
    Console.WriteLine("str.Length is " + str.Length);
    Console.WriteLine("num is " + num);
}