Udostępnij za pomocą


Rzutowanie i konwersje typów (Przewodnik programowania w języku C#)

Ponieważ język C# jest statycznie typowany w czasie kompilacji, po zadeklarowaniu zmiennej nie można go ponownie zadeklarować ani przypisać wartości innego typu, chyba że ten typ jest niejawnie konwertowany na typ zmiennej. Na przykład nie można niejawnie przekonwertować elementu string na int. W związku z tym po zadeklarowaniu i jako intelementu nie można przypisać do niego ciągu "Hello", jak pokazano w poniższym kodzie:

int i;

// error CS0029: can't implicitly convert type 'string' to 'int'
i = "Hello";

Czasami jednak może być konieczne skopiowanie wartości do zmiennej lub parametru metody innego typu. Na przykład może istnieć zmienna całkowita, która musi zostać przekazana do metody, której parametr jest wpisany jako double. Może też być konieczne przypisanie zmiennej klasy do zmiennej typu interfejsu. Tego rodzaju operacje są nazywane konwersjami typów. W języku C#można wykonać następujące rodzaje konwersji:

  • Konwersje niejawne: nie jest wymagana żadna specjalna składnia, ponieważ konwersja zawsze kończy się powodzeniem i żadne dane nie zostaną utracone. Przykłady obejmują konwersje z mniejszych do większych typów całkowitych, konwersje z klas pochodnych do klas bazowych i konwersje rozpiętości.

  • Konwersje jawne (rzuty): konwersje jawne wymagają wyrażenia rzutowego. Kastowanie jest wymagane, gdy informacje mogą zostać utracone podczas konwersji lub gdy konwersja może się nie powieść z innych powodów. Typowe przykłady obejmują konwersję liczbową na typ, który ma mniejszą precyzję lub mniejszy zakres, oraz konwersję wystąpienia klasy bazowej na klasę pochodną.

  • Konwersje zdefiniowane przez użytkownika: konwersje zdefiniowane przez użytkownika używają specjalnych metod, które można zdefiniować w celu włączenia jawnych i niejawnych konwersji między typami niestandardowymi, które nie mają relacji klasy bazowej pochodnej. Aby uzyskać więcej informacji, zobacz Operatory konwersji zdefiniowane przez użytkownika.

  • Konwersje z klasami pomocnika: aby konwertować między niezgodnymi typami, takimi jak liczby całkowite i System.DateTime obiekty, lub ciągi szesnastkowe i tablice bajtowe, można użyć System.BitConverter klasy, System.Convert klasy i Parse metod wbudowanych typów liczbowych, takich jak Int32.Parse. Aby uzyskać więcej informacji, zobacz następujące artykuły:

  • Jak przekonwertować tablicę bajtów na int

  • Jak przekonwertować ciąg na liczbę

  • Jak konwertować między ciągami szesnastkowymi i typami liczbowymi

Niejawne przekształcenia

W przypadku wbudowanych typów liczbowych można dokonać niejawnej konwersji, gdy wartość, która ma być przechowywana, może mieścić się w zmiennej bez obcinania lub zaokrąglania. W przypadku typów całkowitych to ograniczenie oznacza, że zakres typu źródłowego jest odpowiednim podzbiorem zakresu dla typu docelowego. Na przykład zmienna typu long (64-bitowa liczba całkowita) może przechowywać dowolną wartość, którą może przechowywać int (32-bitowa liczba całkowita). W poniższym przykładzie kompilator niejawnie konwertuje wartość num po prawej stronie na typ long, zanim zostanie przypisany do bigNum.

// Implicit conversion. A long can
// hold any value an int can hold, and more!
int num = 2147483647;
long bigNum = num;

Aby uzyskać pełną listę wszystkich niejawnych konwersji liczbowych, zobacz sekcję Niejawne konwersje liczbowe w artykule Wbudowane konwersje liczbowe .

W przypadku typów referencyjnych konwersja niejawna zawsze istnieje z klasy do dowolnej z jej bezpośrednich lub pośrednich klas bazowych lub interfejsów. Nie jest wymagana żadna specjalna składnia, ponieważ klasa pochodna zawsze zawiera wszystkie elementy członkowskie klasy bazowej.

Derived d = new Derived();

// Always OK.
Base b = d;

Konwersje jawne

Jeśli jednak nie można dokonać konwersji bez ryzyka utraty informacji, kompilator wymaga wykonania jawnej konwersji, która jest nazywana rzutacją. Rzutowanie jest sposobem jawnego dokonywania konwersji. Wskazuje, że jesteś świadomy, iż może wystąpić utrata danych lub rzutowanie może zakończyć się niepowodzeniem w czasie wykonywania. Aby wykonać rzutowanie, określ typ miejsca docelowego w nawiasach przed przekonwertowanym wyrażeniem. Poniższy program rzutuje double na int. Program nie kompiluje się bez rzutowania.

double x = 1234.7;
int a;
// Cast double to int.
a = (int)x;
Console.WriteLine(a);
// Output: 1234

Aby uzyskać pełną listę obsługiwanych jawnych konwersji liczbowych, zobacz sekcję Jawne konwersje liczbowe w artykule Wbudowane konwersje liczbowe .

W przypadku typów referencyjnych wymagana jest jawne rzutowanie, jeśli konieczna jest konwersja z typu podstawowego na typ pochodny.

Operacja rzutowania między typami odwołań nie zmienia typu czasu wykonywania obiektu bazowego; zmienia tylko typ wartości, która jest używana jako odwołanie do tego obiektu. Aby uzyskać więcej informacji, zobacz Polymorphism (Polimorfizm).

Wyjątki konwersji typów w czasie wykonywania

W niektórych konwersjach typów obiektów kompilator nie może określić, czy rzutowanie jest prawidłowe. Możliwe jest, że operacja rzutowania, która kompiluje się poprawnie, zakończy się niepowodzeniem podczas wykonywania. Jak pokazano w poniższym przykładzie, rzutowanie typu, które kończy się niepowodzeniem w czasie wykonywania, powoduje zgłoszenie wyjątku InvalidCastException.

Animal a = new Mammal();
Reptile r = (Reptile)a; // InvalidCastException at run time

Jawne rzutowanie argumentu a na Reptile stanowi niebezpieczne założenie. Bezpieczniej jest nie podjąć założeń, ale raczej sprawdzić typ. Język C# udostępnia is operator, aby umożliwić testowanie pod kątem zgodności przed rzeczywistym wykonaniem rzutowania. Aby uzyskać więcej informacji, zobacz Jak bezpiecznie rzutować przy użyciu dopasowywania wzorca i operatorów as i is.

Specyfikacja języka C#

Aby uzyskać więcej informacji, zobacz sekcję Konwersjespecyfikacji języka C#.

Zobacz także