Koska C# on staattisesti tyypitetty käännöaikana, niin sen jälkeen kun muuttuja on määritelty, sitä ei voi uudelleen määrittää, tai siihen ei voi asettaa toisen tyyppistä arvoa joka ei ole muunnettavissa muuttujan (olion) tyyppiin. Esimerkiksi seuraava aiheuttaisi virheen:
int i;
i = "Hello"; // Error: "Cannot implicitly convert type 'string' to 'int'"
Tyyppimuunnos (käytetään myös termiä kastaus, englanninkielistä sana casting) on muuttujatyypin muuntamista joko käännös- tai ajonaikana tyypistä toiseen. Koska C#:ssa kaikki muuttujat ovat olioita, on siis kyseessä olion muuntaminen toiseksi olioksi. Tyyppimuunnokset voidaan tehdä joko eksplisiittisesti tai implisiittisesti.
Implisiittinen muunnos tapahtuu kääntäjän toimesta eikä sen tekemistä varten koodissa ole erityistä komentoa. Implisiittestä muunnoksesta ei koskaan tulla virhettä.
Eksplisiittinen muunnosta eli kastaus (casting) ei koskaan tehdä kääntäjän toimesta, vaan koodiin on kirjoitettu muunnosta varten erityinen komento. Eksplisiittinen muunnos voi aiheuttaa ajonaikaisen virheen, joten siihen täytyy koodissa varautua sopivalla poikkeuskäsittelyllä.
Koska int (32-bittiä) on lukualueena pienempi kuin long (64-bittinen), niin int-tyypin muuttuja voidaan "turvallisesti" implisiittisesti kastata long-tyyppiin.
//implisiittinen kastaus
int i = 54321;
long n = i; //long on lukualueena suurempi kuin int
Koska double on lukualueena suurempi kuin int, niin ei turvallista eikä viisasta muuttaa double-tyypin muuttujaa int-tyyppiseksi, joten kääntäjä ei salli tätä tehdä. Suuremmasta lukualueesta pienempään lukualueeseen muutettaessa voi tapahtua tiedon häviämistä, joten muutokset täytyy tehdä eksplisiittisesti, jos tiedät että tiedon häviäminen ei aiheuta vaikutuksia ohjelmaasi.
//eksplisiittinen kastaus
double d = 654321.0987;
int i;
//muunnos tehdään laittamalla tyyppi suluissa muuttujan eteen
i = (int)d;
Toinen vaihtoehto on käyttää .NET Frameworkin tarjoamaa metodia Convert.
i = Convert.ToInt32(d);
public static void TestaaKastaus()
{
//implisiittinen kastaus
int i;
long n; //long on lukualueena suurempi kuin int
i = int.MaxValue;
n = i; //implisiittinen muutos, ei tarvita kastausta
Console.WriteLine("int {0} on samakuin long {1}",i, n);
//eksplisiittinen kastaus
int i2 = 0;
long n2; //long on lukualueena suurempi kuin int
n2 = long.MaxValue; //longin maksimi 9223372036854775807, ei varmasti mahdu int-lukutyyppiin!
i2 = (int)n2; //eksplisiittinen muutos, vaatii kastauksen
Console.WriteLine("long maksimi {1} ei ole sama int {0}", i2, n2);
}

C# tarjoaa myös valmiita mekanismeja merkkijonojen parseroimiseksi. TryParse() ja Parse() metodit tarjoavat helpotusta kastaukseen.
string syote = Console.ReadLine();
// TryParse() example
bool result = Int32.TryParse(syote, out number);
// Parse() example
int i = Int32.Parse(syote);
Allaoleva kuva esittää miten peritty luokan olio voidaan kastata implisiittisesti kantaluokan olioksi, sillä peritty luokka sisältä aina vähintään kaiken mitä kantaluokkakin. Toistepäin kastaaminen täytyy tehdä eksplisiittesti koska perityn luokan olio voi sisältää enemmän kuin kantaluokan olio.

Alla olevassa esimerkissä on käytetty kahta luokkaa: Animal ja Rat. Rat on peritty kantaluokasta Animal. Suoritetaan oheisen koodin mukainen implisiittinen kastaus.
public static void TestaaKastausOmatOliotImplisiittinen()
{
Console.WriteLine("Demo: implisiittinen kastaus");
//luodaan oliot luokista Animal ja Rat
Animal a = new Animal();
a.Name = "Elukka";
Rat r = new Rat();
r.Name = "Rotta";
Console.WriteLine("Aluksi sinulla on tällaiset elukat: {0} ja {1}", a.Name, r.Name);
//implisiittinen kastaus peritystä luokasta kantaluokkaan
a = r;
Console.WriteLine("Nyt sinulla on tällaiset elukat: {0} ja {1}", a.Name, r.Name);
}

Viittaustyypin eksplisiittinen muutos voidaan tehdä as-operaattorilla. Se tekee muunnoksen mikäli mahdollista. Ellei muunnos ole mahdollinen, palautuu null-arvo. As-operaattoria voi käyttää vain viittaustyypeille, koska arvotyypeillä ei ole null-arvoa.
As-operaattorin etu on siinä että muutoksesta ei tule poikkeusta.
is-operaattorilla voidaan testata onko muuttuja tiettyä tyyppiä (tai toteuttaako se tietyn rajapinnan).
Se palauttaa true tai false. Sitä käytetään lähinnä tarkistuksissa, koska sillä ei voi tehdä itse muutoksia.
Casting and type conversions (C# Programming Guide)