Entwickler-Ecke
C# - Die Sprache - Wie zeigt man richtig auf die Instanz einer Klasse ?
miniC# - Do 05.02.09 12:31
Titel: Wie zeigt man richtig auf die Instanz einer Klasse ?
Hallo,
ich habe mal wieder ein sehr grundlegendes Problem. Ich habe ein Programm mit einer einfachen Nodestruktur, welche jeweils einen Wert enthält, der auf einen anderen Node zeigt. Der Node auf welchen gezeigt wird, soll verändert werden können. Ich habe dies jetzt einfach mit meinem guten alten Freund
ref gelöst. Ist dies die richige Herangehensweise für mein Problem oder muss ich mich da in für mich kryptische Themen wie Pointer oder Delegaten einlesen ? Irgendwie erscheint mir die Lösung sehr unsauber ;)
so schaut der code grob aus (leider grad net daheim und kein zugriff auf den orginaltext) :
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| public abstract class EffectorNode { internal List<EffectorNode> subnodes; internal EffectorNode pointonnode; }
public class myEffector : EffectorNode { public myEffector(ref EffectorNode Target, List<EffectorNode> Subnodes) { subnodes = Subnodes; pointonnode = Target; } } |
edith sagt : die bäumen können recht groß werden ;) bis zu 1000 nodes sind keine ausnahme ;)
bakachan - Do 05.02.09 12:36
Wenn es sich um eine Objekttypen handelt die übergeben wird wird in C# standardmäßig nur die reference übergeben und somit ist ref meist überflüssig (außnahme: wenn es sich um Werttypen handelt).
edit:
Ok hab ich vielleicht etwas falsch ausgedrückt.
Bei Objekttypen:
- ohne ref -> man arbeitet direkt mit dem Objekt
man kann z.b. Properties des Objekts verändern usw aber wenn man das Objekt ersetzt wird das außerhalb nicht mit ersetzt (reicht in dem von MiniC# beschriebenen Fall aus)
- mit ref -> man arbeitet mit der Adresse des Objekts
quasi das gleiche wie oben nur das man auch das objekt an sich ersetzen kann
Christian S. - Do 05.02.09 14:31
Überflüssig ist
ref auch bei Referenzdatentypen nicht. Beispiel:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31:
| class Test { public string Text { get; set; } }
class Program { static void OhneRef(Test test) { test = new Test(); test.Text = "foo"; }
static void MitRef(ref Test test) { test = new Test(); test.Text = "foo"; }
static void Main(string[] args) { Test test = new Test(); test.Text = "bar"; Console.WriteLine(test.Text); OhneRef(test); Console.WriteLine(test.Text); MitRef(ref test); Console.WriteLine(test.Text); Console.ReadKey(); } } |
Ausgabe:
UGrohne - Do 05.02.09 19:05
Zur Erklärung der Phänomene:
Werttypen wie in int, double usw werden direkt auf dem Stack gespeichert und die Variable enthält den Wert. Variablen auf Objekttypen jedoch enthalten einen Verweis auf die Daten im Heap. Und der Inhalt der Variable wird im Standard übergeben. D.h. bei Werttypen arbeitest Du mit einer Kopie des Wertes (neues Element auf dem Stack) und bei Verweistypen arbeitest Du mit einer Kopie des Verweises (auch wieder auf dem Stack. Bei Übergabe mit ref wird mit der Variablen selbst gearbeitet.
So lässt sich einerseits erklären, warum normal übergebene Objekte auch ohne ref geändert werden können. Aber auch, warum Christians Beispiel nur mit ref funktioniert: In der Methode wird ein neues Objekt erstellt und der Verweis in dem übergebenen Parameter gespeichert. Ohne ref kriegt das natürlich die ursprüngliche Variable nicht mit (sie wird ja nicht geändert) und zeigt auf den alten Bereich auf dem Heap, mit ref wird diese Variable auf dem Stack jedoch geändert und zeigt auf das neue Objekt auf dem Heap.
Mit ner Zeichnung ist das anschaulicher, aber ich hoffe, es ist einigermaßen verständlich erklärt und hilft Dir weiter.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!