Ach, da hätte ich noch was vergessen:

Code:
int a = 5;
int b = 5;

Circle c1 = new Circle();
c1.Radius = 10;

Circle c2 = new Circle();
c2.Radius = 10;

Circle c3 = c1;

boolean b1 = a == b; // ergibt True
boolean b2 = c1 == c2, // ergibt False
boolean b3 = c1 == c3; // ergibt True
b1 vergleicht die Werte. b2 und b3 vergleichen allerdings die Referenzen.
Auch hier wird deutlich, dass wir mit Pointern arbeiten. Wer c1 und c2 vergleichen möchte, muss die Equals()-Methode verwenden, und ggf. sogar die Equals()-Methode oder den Vergleichsoperator überschreiben.

Zitat Zitat von RPG Hacker Beitrag anzeigen
So kannst du beispielsweise einen int niemals als Referenztyp und eine Klasse niemals als Valuetyp übergeben. Das ist zwar nur in den seltensten Fällen überhaupt nötig, aber durchaus nicht komplett ausgeschlossen. Zumindest der erste Fall. Um das in C# hinzukriegen musst du schon einen Umweg gehen und den Valuetyp irgendwie extra in eine Klasse packen. Und das ist eben genau das, was ich meine. Wirklich mit Pointern arbeiten tust du in C# eigentlich nur in Unmanaged Code. Ansonsten tut C# das automatisch und es kann dir egal sein, ob da gerade Pointer verwendet werden oder nicht. Eben auch wegen der automatischen Speicherverwaltung und so.
Wie Corti schon sagt:
Im ersten Fall gibt es die Schlüsselwörter ref und out.
Im zweiten Fall gibt es die Structs, die nämlich im Stack alloziert werden und somit als Wertetypen gelten.

Structs sind aber ein Überbleibsel aus der strukturellen Programmierung. Klassen sind im Prinzip eine Erweiterung der Structs. In dieser Hinsicht ist C# nicht ganz konsequent. Es kann aber durchaus Sinnvoll sein, unter C# Structs zu verwenden, weil hier der Overhead deutlich geringer ist. Wer also viele Objekte auf einmal erzeugen muss, die nur Daten bereitstellen, kann mit Structs ein wenig Performance rausholen, aber C# ist hier eine Ausnahme. Z.B. unter Java gibt es für beide Fälle keine Lösung.

Zitat Zitat von RPG Hacker Beitrag anzeigen
Wenn du beispielsweise eine Funktion mit Parametern schreibst, macht es für dich keinen Unterschied, ob du einen int übergibst oder eine Klasse. C# wählt automatisch die bestmögliche Option für dich.
C# sucht keine Option aus. C# erzeugt eine Kopie. Entweder eine Kopie des Wertetyps, oder eine Kopie der Referenz, je nachdem um was für ein Typ es sich handelt.