abstract | as | base | bool | break |
byte | case | catch | char | checked |
class (1) | const (1) | continue | decimal | default |
delegate | do | double | else | enum |
event | explicit | extern | false | finally |
fixed | float | for | foreach | get |
goto (1) | if | implicit | in | int |
interface | internal | is | lock | long |
namespace | new (1) | null | object (1) | operatror |
out | override | params | private | protected |
public | readonly | ref | return | sbyte |
sealed | set | short | sizeof | stackalloc |
static | string | struct (1) | switch | this |
throw | true | try | typeof | uint |
ulong | unchecked | unsafe | ushort | using |
value | virtual | void | while |
Code | Résultat | Remarques |
using System; namespace Exemples { class TestTypesValeur { static void Main(string[] args) { int x = 33; int y = x; // assigne x à y, y est maintenant une copie de x x++; // incrémente x à 34 Console.WriteLine(y); // affiche 33 Console.ReadKey(); } } } |
33 |
Le type int contient un entier qui est copié par valeur. |
Code | Résultat | Remarques |
using System; using System.Text; namespace Exemples { class TestTypesReference1 { static void Main(string[] args) { StringBuilder x = new StringBuilder("Bonjour"); StringBuilder y = x; x.Append(" tout le monde !"); Console.WriteLine(y); // affiche Bonjour tout le monde ! Console.ReadKey(); } } } |
Bonjour tout le monde ! |
Le type StringBuilder est un type référence. Lorsque nous déclarons la variable StringBuilder, nous faisons en fait deux choses différentes qui peuvent être séparées en deux lignes :StringBuilder x; x = new StringBuilder("Bonjour");La première ligne crée une nouvelle variable qui peut contenir une référence à un objet StringBuilder. La seconde ligne assigne un nouvel objet StringBuilder à la variable. Lorsque nous assignons x à y, nous faisons en sorte que y pointe sur le même objet que x. Une référence contient l'adresse d'un objet (une adresse est un emplacement mémoire stocké comme un nombre de 4 octets). Nous créons ainsi une copie de x, mais nous copions ce nombre de 4 octets plutôt que l'objet StringBuilder lui-même. |
using System; using System.Text; namespace Exemples { class TestTypesReference2 { static void Main(string[] args) { StringBuilder x = new StringBuilder("Bonjour"); StringBuilder y = x; x = null; y.Append(" tout le monde !"); Console.WriteLine(y); // affiche Bonjour tout le monde ! Console.ReadKey(); } } } |
Bonjour tout le monde ! |
Une référence peut ne pointer vers aucun objet en assignant la référence à null. Ici, nous assignons null à x, mais nous pouvons toujours accéder au même objet StringBuilder que nous avons créé via y. |
Code | Résultat | Remarques |
using System; namespace Exemples { // Déclaration type référence class PointReference { public int x, y; } // Déclaration type valeur struct PointValeur { public int x, y; } // Test class TypesValeurEtReferenceCoteACote1 { static void Main(string[] args) { PointReference a; // type référence a = new PointReference(); PointValeur b; // type valeur b = new PointValeur(); a.x = 7; b.x = 7; Console.ReadKey(); } } } |
A la fin de la méthode, les variables locales a et b son hors de portée, mais la nouvelle instance d'un pointReference reste en mémoire jusqu'à ce que le ramasse-miettes détermine qu'elle n'est plus référencée. | |
using System; namespace Exemples { // Déclaration type référence class PointReference { public int x, y; } // Déclaration type valeur struct PointValeur { public int x, y; } // Test class TypesValeurEtReferenceCoteACote2 { static void Main(string[] args) { PointReference a; // type référence a = new PointReference(); PointValeur b; // type valeur b = new PointValeur(); a.x = 33; b.x = 33; PointReference c = a; PointValeur d = b; c.x = 91; d.x = 91; Console.WriteLine(a.x); // affiche 91 Console.WriteLine(b.x); // affiche 33 Console.ReadKey(); } } } |
91 33 |
Une assignation à un type référence copie la référence d'un objet tandis qu'une assignation à un type valeur copie la valeur d'un objet. Un objet sur le tas peut être pointé sur de multiples variables. Un objet sur la pile ou en ligne (inline) ne peut être accédé que via la variable avec laquelle il a été créé. |
Code | Résultat | Remarques |
using System; namespace Exemples { class BoxingEtUnboxingDeTypesValeur1 { static void Main(string[] args) { int x = 33; Console.WriteLine(x); // affiche 33 object o = x; // boxing de int Console.WriteLine(o); // affiche 33 int y = (int)o; // unboxing de int Console.WriteLine(y); // affiche 33 try { string z = (string)o; // unboxing de int dans string impossible } catch (Exception e) { Console.WriteLine(e.GetType()); // System.InvalidCastException } Console.ReadKey(); } } } |
33 33 33 System.InvalidCastException |
Ici, nous faisons du boxing et de l'unboxing avec un type valeur int. Lorsqu'un type valeur est mis en boite (boxed), un nouveau type référence est créé pour contenir une copie de type valeur. L'unboxing copie la valeur du type référence à un type valeur. L'unboxing requiert un transtypage explicite. Une vérification est faite afin de s'assurer que le type valeur vers lequel vous souhaitez le convertir correspond bien au type contenu dans le type référence. Une erreur InvalidCastException survient si la vérification échoue. |
using System; using System.Collections; namespace Exemples { class BoxingEtUnboxingDeTypesValeur2 { static void Main(string[] args) { Queue q = new Queue(); q.Enqueue(33); // boxing de int q.Enqueue(" CH "); // boxing de " CH " q.Enqueue(91); // boxing de int Console.Write((int)q.Dequeue()); // unboxing de int Console.Write((string)q.Dequeue()); // unboxing de string Console.WriteLine((int)q.Dequeue()); // unboxing de int Console.ReadKey(); } } } |
33 CH 91 |
L'utilisation des classes de collection est un bon exemple de technique de boxing et d'unboxing. Ici, nous utilisons la classe Queue avec des types valeurs. |
int i = 33; System.Int32 i = 33;
Type C# | Type System | Taille | Signé |
sbyte | System.SByte | 1 octet | Oui |
short | System.Int16 | 2 octets | Oui |
int | System.Int32 | 4 octets | Oui |
long | System.Int64 | 8 octets | Oui |
byte | System.Byte | 1 octet | Non |
ushort | System.UInt16 | 2 octets | Non |
uint | System.UInt32 | 4 octets | Non |
ulong | System.UInt64 | 8 octets | Non |
Code | Résultat | Remarques |
using System; namespace Exemples { class TypesEntier1 { static void Main(string[] args) { int x = 33; // utilisation du préfixe 0x pour hexadécimal ulong y = 0x21; // 2 * 16 + 1 = 33 Console.WriteLine((ulong)x - y); // affiche 0 Console.ReadKey(); } } } |
0 |
Les entiers littéraux peuvent utiliser aussi bien une notation décimal qu'hexadécimale. |
using System; namespace Exemples { class TypesEntier2 { static void Main(string[] args) { Console.WriteLine((0xFF).GetType()); // 1 octet => System.Int32 Console.WriteLine((0xFFFF).GetType()); // 2 octets => System.Int32 Console.WriteLine((0xFFFFFF).GetType()); // 3 octets => System.Int32 Console.WriteLine((0xFFFFFFFF).GetType()); // 4 octets => System.UInt32 Console.WriteLine((0xFFFFFFFFFF).GetType()); // 5 octets => System.Int64 Console.WriteLine((0xFFFFFFFFFFFF).GetType()); // 6 octets => System.Int64 Console.WriteLine((0xFFFFFFFFFFFFFF).GetType()); // 7 octets => System.Int64 Console.WriteLine((0xFFFFFFFFFFFFFFFF).GetType()); // 8 octets => System.UInt64 Console.ReadKey(); } } } |
System.Int32 System.Int32 System.Int32 System.UInt32 System.Int64 System.Int64 System.Int64 System.UInt64 |
Lorsqu'un type entier littéral est valide pour différents types entiers, le type par défaut est choisi dans cet ordre : int, uint, long et ulong. |
using System; namespace Exemples { class TypesEntier3 { static void Main(string[] args) { Console.WriteLine(((ulong)0xFF).GetType()); // 8 octets => System.UInt64 Console.WriteLine((0xFFUL).GetType()); // 8 octets => System.UInt64 Console.WriteLine((255UL).GetType()); // 8 octets => System.UInt64 Console.WriteLine((255U).GetType()); // 8 octets => System.UInt32 Console.WriteLine((255L).GetType()); // 8 octets => System.Int64 Console.ReadKey(); } } } |
System.UInt64 System.UInt64 System.UInt64 System.UInt32 System.Int64 |
Les suffixes suivants peuvent être utilisés pour spécifier explicitement le type choisi :
|
Code | Résultat | Remarques |
using System; namespace Exemples { class ConvertirDesEntiers { static void Main(string[] args) { int x = 123456; // 123456 = 0x1E240 Console.WriteLine(x); // affiche 1213456 long y = x; // conversion implicite, pas d'information perdue Console.WriteLine(y); // affiche 1213456 short z = (short)x; // conversion explicite, tronque x à 2 octets => 0xE240 = -7616 Console.WriteLine(z); // affiche -7616 Console.ReadKey(); } } } |
123456 123456 -7616 |
Vous pouvez convertir implicitement un int vers un long, mais une conversion explicite est requise pour convertir un int vers un short. |
Type C# | Type System | Taille |
float | System.Single | 4 octets |
double | System.Double | 8 octets |
Code | Résultat | Remarques |
using System; namespace Exemples { class TypesNombreAVirguleFlottante { static void Main(string[] args) { float g = 9.81f; // affiche System.Single : 9,81 Console.WriteLine(g.GetType() + " : " + g.ToString()); double N = 6.02E23; // affiche System.Double : 6,02E+23 Console.WriteLine(N.GetType() + " : " + N.ToString()); Console.ReadKey(); } } } |
System.Single : 9,81 System.Double : 6,02E+23 |
Les nombres littéraux à virgule flottante peuvent utiliser une notation décimale ou exponentielle. Un flottant littéral requiert le suffixe f ou F. On peut choisir le suffixe d ou D pour un double littéral. |
Code | Résultat | Remarques |
using System; namespace Exemples { class ConvertirDesNombreAVirguleFlottante1 { static void Main(string[] args) { int a = 33; int b = 91; // y = 33 * 33,91 + 91 = 1210,03 float y = a * 33.91f + b; // affiche 1210,03 Console.WriteLine(y.ToString()); Console.ReadKey(); } } } |
1210,03 |
Si cet exemple utilisait des valeurs plus grandes, la précision serait perdue. |
using System; namespace Exemples { class ConvertirDesNombreAVirguleFlottante2 { static void Main(string[] args) { float grosso = 33.91f; // affiche 33,91 Console.WriteLine(grosso.ToString()); int famille = (int)grosso; // affiche 33 Console.WriteLine(famille.ToString()); Console.ReadKey(); } } } |
33,91 33 |
Toutes les autres conversions entre des types entier et des types flottant doivent être explicites. |
Code | Résultat | Remarques |
using System; namespace Exemples { class TypeDecimal { static void Main(string[] args) { float f = 13391.3391f; // affiche 13391,34 Console.WriteLine(f.ToString()); decimal d = 13391.3391m; // affiche 13391,3391 Console.WriteLine(d.ToString()); Console.ReadKey(); } } } |
13391,34 13391,3391 |
Dans cet exemple, on voit la capacité du type décimal à stocker des nombres en base 10 sans erreur. |
Code | Résultat | Remarques |
using System; namespace Exemples { class ConvertirDesDecimaux { static void Main(string[] args) { int i = 133913391; // affiche 133913391 Console.WriteLine(i.ToString()); decimal d = i; // affiche 133913391 Console.WriteLine(d.ToString()); float f = (float)d; // affiche 1,339134E08 Console.WriteLine(f.ToString()); Console.ReadKey(); } } } |
133913391 133913391 1,339134E08 |
Une conversion implicite de tous types entier vers un type décimal est permise parce qu'un décimal peut représenter toutes valeurs de type entier. Une conversion d'un type décimal vers un type flottant ou vice versa nécessite une conversion explicite. |
Type C# | Type System | Taille |
char | System.Char | 2 octets |
Code | Résultat | Remarques |
using System; namespace Exemples { class TypeChar { static void Main(string[] args) { // caratères simples char c3 = '3'; char c9 = '9'; char c1 = '1'; // unicode char cC = '\u0043'; // unsigned short hexadecimal char cH = '\x0048'; // caractères d'échappement char CR = '\r'; char LF = '\n'; // construction de chaînes de caractères string trenteTrois = c3.ToString() + c3.ToString(); string CH = cC.ToString() + cH.ToString(); string quatreVingtOnze = c9.ToString() + c1.ToString(); string CRLF = CR.ToString() + LF.ToString(); // affiche 33 // CH // 91 string message = trenteTrois + CRLF + CH + CRLF + quatreVingtOnze ; Console.WriteLine(message); Console.ReadKey(); } } } |
33 CH 91 |
Dans cet exemple, on voit apparaître :
|
Char | Signification | Valeur |
\' | Apostrophe | 0x0027 |
\" | Guillemet | 0x0022 |
\\ | Antislash | 0x005C |
\0 | Null | 0x0000 |
\a | Alerte | 0x0007 |
\b | Retour arrière | 0x0008 |
\f | Avance chariot | 0x000C |
\n | Nouvelle ligne | 0x000A |
\r | Retour chariot | 0x000D |
\t | Tabultation horizontale | 0x0009 |
\v | Tabultation verticale | 0x000B |
Code | Résultat | Remarques |
using System; namespace Exemples { class ConvertirDesChar { static void Main(string[] args) { char A = 'A'; Console.WriteLine(A); // affiche A int intA = A; Console.WriteLine(intA); // affiche 65 byte byteA = (byte)A; Console.WriteLine(byteA); // affiche 65 Console.ReadKey(); } } } |
A 65 65 |
La conversion implicite d'un char vers la plupart des types numériques fonctionne si ce dernier peut être traité comme un unsigned short. Dans le cas contraire, une conversion explicite est requise. |
Type C# | Type System | Taille |
bool | System.Boolean | 1 octet / 2 octets |
Code | Résultat | Remarques |
using System; namespace Exemples { class ConvertirDesBooleens { static void Main(string[] args) { bool flag = true; Console.WriteLine(flag); // affiche True int intFlag = convertBool(flag); Console.WriteLine(intFlag); // affiche 1 flag = false; Console.WriteLine(flag); // affiche False intFlag = convertBool(flag); Console.WriteLine(intFlag); // affiche 0 Console.ReadKey(); } static int convertBool(bool abFlag) { if (abFlag) { // vrai return 1; } else { // faux return 0; } } } } |
True 1 False 0 |
Aucune conversion de booléens vers des types numériques ne peut être réalisée et réciproquement... |
Type C# | Type System | Taille |
object | System.Object | 0 octet / 8 octets et plus |
Type C# | Type System | Taille |
string | System.String | Minimum 20 octets |
Code | Résultat | Remarques |
using System; namespace Exemples { class TypeString { static void Main(string[] args) { string s1 = "\\\\aci-prod\\DIRTEC"; string s2 = @"\\aci-prod\DIRTEC"; Console.WriteLine(s1 == s2); // affiche True s1 = "Première ligne\r\nSeconde ligne"; s2 = @"Première ligne Seconde ligne"; Console.WriteLine(s1 == s2); // affiche True Console.ReadKey(); } } } |
True True |
Dans ces deux exemples, à chaque fois, les deux chaînes s1 et s2 sont identiques. |