En C#, il existe deux catégories de type :
Un type de base est un type simple "valeur".
Syntaxe des chaînes de caractères.
Comme illustré par l'exemple du tableau ci-dessus, une chaîne de caractères peut avoir deux syntaxes différentes :
Exemples :
"un guillemet \", un anti-slash \\, un retour à la ligne\n"
@"un guillemet "", un anti-slash \, un retour à la ligne
La syntaxe "verbatim" simplifie la frappe des chemins de fichiers qui utilisent le caractère anti-slash comme séparateur :
@"C:\program files\monapp\monfichier.txt"
Auto-boxing/unboxing.
Chaque type de données correspond à une classe de l'espace de nom codice_8.
La conversion entre le type et une instance de cette classe est implicite et invisible.
Ainsi, on peut appeler des méthodes sur les types simples, affecter une constante où une classe de type est attendue (et "vice versa"), ...
Exemple :
int a = 25;
string message = 36.ToString(); // convertit 36 en chaîne de caractères,
 // méthode définie dans la classe System.Int32
UInt32 b = 50;
Types "nullable".
Le langage C#2.0 introduit la possibilité pour les types simples de valoir codice_1. Cette fonctionnalité permet une meilleure interopérabilité avec les bases de données qui utilisent ce type de données.
Pour qu'une variable puisse valoir codice_1 ("nullable"), il faut que le type soit suivi d'un point d'interrogation. Par exemple :
int? numero = null;
Il est donc possible de tester qu'une variable de ce type vaut codice_1 :
if (numero==null) numero = 50;
else numero++;
Le nouvel opérateur codice_12 (double point d'interrogation) permet de sélectionner l'opérande de gauche s'il ne vaut pas codice_1, ou l'opérande de droite sinon :
 "valeur_ou_null"??"valeur_si_null"
Cet opérateur est donc pratique à utiliser avec les types "nullables" pour obtenir une valeur par défaut :
Console.WriteLine("Numéro : "+( numero??50 ));
Valeur par défaut.
L'opérateur codice_14 retourne la valeur par défaut du type spécifié. Il s'agit de la valeur quand une variable de ce type n'est pas initialisée (codice_15 pour les nombres, codice_1 pour les types références).
Exemple :
public int absolu(int? valeur)
 if (valeur==null) return default(int);
 else return (valeur<0) ? -valeur : valeur;
L'utilité de cet opérateur est plus évident avec l'utilisation de types génériques.
Obtenir le type.
L'opérateur codice_17 retourne une instance de la classe System.Type pour le type spécifié entre parenthèses.
Exemple :
Type t=typeof(int);
L'utilité de cet opérateur est plus évident avec l'utilisation de types génériques.
Obtenir le nom.
L'opérateur codice_18 retourne le nom d'une variable ou d'une méthode sous la forme d'une chaîne de caractères déterminée à la compilation.
Exemple :
var nombres = new List<int> { 1, 2, 3 };
Console.WriteLine(nameof(nombres)); // nombres
Console.WriteLine(nameof(nombres.Count)); // Count
Exemple d'utilisation dans la génération d'exception en cas d'échec de vérification des arguments :
public string Name
 get => name;
 set => name = value ?? throw new ArgumentNullException(nameof(value), $"{nameof(Name)} cannot be null");
Type variable.
Le langage C#3.0 introduit la possibilité de détecter le type des variables locales selon le type de la valeur ou du résultat d'une expression affecté à cette variable.
Il s'agit d'un typage implicite, et cela demeure un typage fort.
Ce qui signifie qu'il n'est pas possible ensuite d'affecter une valeur d'un type incompatible.
Exemple 1 :
var n = 50; // Typage implicite équivalent à : int n = 50;
n = 100; // OK
n = "Autre"; // Erreur, n'est pas un entier
n = 1.23; // Erreur, n'est pas un entier
Exemple 2 :
var nom = "Exemple"; // Typage implicite équivalent à : string nom = "Exemple";
nom = "Autre"; // OK
nom = 100; // Erreur, n'est pas une chaîne de caractères
nom = 1.23; // Erreur, n'est pas une chaîne de caractères
Une variable déclarée avec le mot-clé codice_19 doit obligatoirement être affectée à une valeur ou une expression afin que le compilateur puisse déterminer son type.
var x; // Erreur