Διαδρομές
/
C#
C#
/
Ύλη
/
Μετατροπή τύπων
Με

Μετατροπή τύπων σε C#

4 ασκήσεις

Σχετικά με την έννοια Μετατροπή τύπων

Το casting και η μετατροπή τύπων είναι διαφορετικοί τρόποι να αλλάξεις μια έκφραση από έναν τύπο δεδομένων σε έναν άλλο.

Η τεκμηρίωση της C# κατατάσσει τη μετατροπή τύπων ως τη χρήση του τελεστή as ή του τελεστή is. Το casting ορίζεται ως η χρήση του τελεστή cast.

Στη C#, πολύ συχνά, έξω από τον χώρο των αριθμητικών τιμών και των ιεραρχιών κλάσεων, θα χρειαστεί να κάνεις μια μετατροπή καλώντας κάποιο μέλος του τύπου «προς», όπως η Int32.Parse() που μετατρέπει μια συμβολοσειρά σε ακέραιο, ή καλώντας ένα μέλος του τύπου «από», π.χ. object.ToString(). Οι προγραμματιστές της JavaScript και άλλων δυναμικών γλωσσών θα πρέπει να το έχουν υπόψη.

Σημείωσε ότι υπάρχουν τελεστές άρρητης και ρητής μετατροπής (που συζητούνται στο operator-overloading) και μπορούν να προσφέρουν αρκετά αυθαίρετο casting στους δικούς σου τύπους.

Casting πρωτόγονων τύπων - Άρρητο

Το σύστημα τύπων της C# είναι κάπως αυστηρότερο από αυτό της C ή της JavaScript και κατά συνέπεια οι πράξεις casting είναι πιο περιορισμένες. Το άρρητο casting πραγματοποιείται ανάμεσα σε δύο αριθμητικούς τύπους, αρκεί ο τύπος «προς» να μπορεί να διατηρήσει την κλίμακα και το πρόσημο της τιμής του τύπου «από». Πρόσεξε στην τεκμηρίωση την εξαίρεση για τη μετατροπή σε πραγματικούς αριθμούς, όπου μπορεί να χαθεί ακρίβεια.

Μια άρρητη μετατροπή δεν δηλώνεται με κάποια ειδική σύνταξη. Για παράδειγμα:

int myInt = 1729;
long myLong = myInt;

Δεν υπάρχει άρρητη μετατροπή μιας αριθμητικής (ή συμβολοσειράς) έκφρασης σε bool. Η Βιβλιοθήκη Βασικών Κλάσεων (BCL) παρέχει τη Convert.ToBoolean() για αυτόν τον σκοπό.

Μια έκφραση τύπου char μπορεί να μετατραπεί άρρητα σε int. Η μετατροπή στην αντίθετη κατεύθυνση πρέπει να είναι ρητή. Δεν είναι όλες οι τιμές του int έγκυροι χαρακτήρες utf 16.

Casting πρωτόγονων τύπων - Ρητό

Όπου οι αριθμητικοί τύποι δεν μπορούν να μετατραπούν άρρητα, μπορείς γενικά να χρησιμοποιήσεις τον τελεστή ρητής μετατροπής.

Όταν η τιμή που μετατρέπεται δεν μπορεί να αναπαρασταθεί από τον τύπο «προς», επειδή δεν είναι αρκετά ευρύς ή υπάρχει σύγκρουση προσήμου, τότε στην περίπτωση των ακεραίων μπορεί να πεταχτεί μια εξαίρεση υπερχείλισης, ή στην περίπτωση των float και double η μεταβλητή του τύπου «προς» μπορεί να πάρει την τιμή Infinity.

Μια έκφραση τύπου int μπορεί να μετατραπεί ρητά σε char. Αυτό μπορεί να οδηγήσει σε ένα μη έγκυρο char.

Casting πρωτόγονων τύπων - Παραδείγματα

int largeInt = Int32.MaxValue;
int largeNegInt = Int32.MinValue;
ushort shortUnsignedInt = ushort.MaxValue;
float largeFloat = float.MaxValue;
float smallFloat = 17.29f;

// implicit cast
int from_ushort = shortUnsignedInt;          // 65535
float from_int = largeInt;                   // -21474836E+09
int from_char = 'a';                         // 96

// explicit cast
uint from_largeInt = (uint)largeInt;         // 2147483647
uint from_neg = (uint) largeNegInt;          // 2147483648 or OverflowException is thrown (if checked)
int from_smallFloat = (int) smallFloat;      // 17
int from_largeFloat = (int) largeFloat;      // -2147483648 or OverflowException is thrown (if checked)
char from_intc = (char) 32;                  // ' '
char from_invalid_int = (char) 0xdcbf;       // invalid char - no exception thrown

// no cast available
int fromString = Int32.Parse("42");          // 42
string toString = largeInt.ToString();       // "2147483647"
int fromString_bad = Int32.Parse("forty two");     // FormatException is thrown

Δες αυτό το άρθρο για τη λέξη-κλειδί checked.

Μετατροπή τύπων για τύπους σε μια ιεραρχία

Οποιοσδήποτε τύπος μπορεί να μετατραπεί άρρητα στη βασική του κλάση ή διεπαφή.

IList<int> ll = new List<int>();

Ένας τελεστής cast μπορεί να χρησιμοποιηθεί για τη μετατροπή από μια βασική σε μια παράγωγη κλάση.

IList<int> ll = new List<int>();
List<int> l = (List<int>)ll;

Αν η μετατροπή αποτύχει επειδή ο τύπος της έκφρασης που μετατρέπεται δεν σχετίζεται με τον τύπο προς τον οποίο μετατρέπεται, πετιέται ένα στιγμιότυπο της InvalidCastException.

Μια πιο συνηθισμένη προσέγγιση σε αυτές τις μετατροπές τύπων είναι να χρησιμοποιήσεις τη λέξη-κλειδί is:

interface IFoo { int Bar(); }
class Foo : IFoo { public int Bar() { return 42; }}
Object r = new Random();
IFoo ifoo = new Foo();
Object o = new Foo();

int result = 1729;

if (ifoo is Foo foo)
{
    result = foo.Bar();
}
// result == 42

result = 1729;
if (o is Foo foo2)
{
    result = foo2.Bar();
}
// result == 42

result = 1729;
if (r is Foo foo3)
{
    result = foo3.Bar();
}
// result == 1729

Η λέξη-κλειδί as επιτελεί παρόμοια λειτουργία με το is, π.χ. var foo = ifoo as Foo;. Σε αυτό το παράδειγμα, το foo θα είναι null αν το ifoo δεν είναι τύπου Foo, διαφορετικά το ifoo θα ανατεθεί σε αυτό.

Προσαρμοσμένος τελεστής cast

Οι τύποι μπορούν να ορίσουν τους δικούς τους προσαρμοσμένους τελεστές cast, ρητούς και άρρητους.

Παραδείγματα ρητών και άρρητων μετατροπών στη BCL είναι οι μετατροπές από και προς τη δομή BigInteger και άλλους αριθμητικούς τύπους

Χρήση του typeof

Αν χρειάζεται να εντοπίσεις τον ακριβή τύπο ενός αντικειμένου, τότε το is μπορεί να είναι λίγο πολύ επιτρεπτικό, καθώς θα μετατρέψει ένα αντικείμενο σε μια κλάση ή σε κάποια από τις βασικές της κλάσεις. Σε αυτή την περίπτωση, η λύση είναι το typeof και η Object.GetType().

object o = new List<int>();

o is ICollection<int> // true
o.GetType() == typeof(ICollection<int>) // false
o is List<int> // true
o.GetType() == typeof(List<int>) // true
Επεξεργασία μέσω GitHub Ο σύνδεσμος ανοίγει σε νέο παράθυρο ή καρτέλα

Μάθε την έννοια Μετατροπή τύπων

Η εξάσκηση είναι κλειδωμένη

Ξεκλείδωσε 3 ακόμη ασκήσεις για να εξασκηθείς στην έννοια Μετατροπή τύπων