Laden...

[erledigt] Flat List zu Tree Code - Erklärung benötigt [==> Klassen sind Referenztypen]

Erstellt von coga vor 9 Jahren Letzter Beitrag vor 9 Jahren 1.032 Views
Thema geschlossen
C
coga Themenstarter:in
12 Beiträge seit 2011
vor 9 Jahren
[erledigt] Flat List zu Tree Code - Erklärung benötigt [==> Klassen sind Referenztypen]

Hi zusammen,
ich erstelle aus einer Flachen Liste einen Baum, dazu hab ich auf Stackoverflow das Beispiel Building a tree using a list of objects gefunden. Nun steh ich jedoch wegen dem Verhalten des Codes etwas auf den Schlauch und kann es mir einfach nicht erklären.
Erstmal der Code:

class Program
{
    static void Main(string[] args)
    {
        List<Task> flat = new List<Task>();
        flat.Add(new Task(0, null, "First node"));
        flat.Add(new Task(1, 0, "First child"));
        flat.Add(new Task(2, 0, "Second child"));
        flat.Add(new Task(3, 2, "First child of \"First child\""));
        flat.Add(new Task(4, 2, "Second child of \"First child\""));
        flat.Add(new Task(5, 0, "Third child"));
        flat.Add(new Task(6, 5, "First child of \"Third child\""));
        flat.Add(new Task(7, 5, "Second child of \"Third child\""));


        List<Task> tree = Task.MakeTreeFromFlatList(flat);
    }
}
    
public class Task
{
    public int Id { get; set; }
    public Nullable<int> ParentId { get; set; }
    public string Description { get; set; }
    public List<Task> Children { get; set; }

    public Task()
    {
        this.Children = new List<Task>();
    }
    
    public Task(int Id, Nullable<int> ParentId, string Description)
    {
        this.Id = Id;
        this.ParentId = ParentId;
        this.Description = Description;
        this.Children = new List<Task>();
    }

    public override string ToString()
    {
        return string.Format("Id: \"{0}\" - ParentId: \"{1}\" - Children.Count: \"{2}\" - Description: {3}", this.Id, this.ParentId, this.Children.Count, this.Description);
    }

    public static List<Task> MakeTreeFromFlatList(IEnumerable<Task> flatList)
    {
        Dictionary<int, Task> dic = flatList.ToDictionary(n => n.Id, n => n);
        List<Task> rootNodes = new List<Task>();
        foreach (Task node in flatList)
        {
            if (node.ParentId.HasValue)
            {
                Task parent = dic[node.ParentId.Value];
                parent.Children.Add(node);
            }
            else
            {
                rootNodes.Add(node);
            }
        }
        return rootNodes;
    }
}

Vom Ergebnis her funktioniert der Code, jedoch versteh ich nicht wieso die Zeile "parent.Children.Add(node);" in "MakeTreeFromFlatList" Auswirkungen auf das Dictionary "dic" und die Liste "rootNodes" hat. Ich steh da gerade total auf dem Schlauch und wäre euch dankbar wenn mir jmd. das Verhalten erklären könnte.

5.658 Beiträge seit 2006
vor 9 Jahren

Hi coga,

jedoch versteh ich nicht wieso die Zeile "parent.Children.Add(node);" in "MakeTreeFromFlatList" Auswirkungen auf das Dictionary "dic" und die Liste "rootNodes" hat.

Hat es nicht, das Dictionary wird mit der Enumerable.ToDictionary-Methode erstellt.

Geh mal mit dem Debugger durch den Code, dann siehst du schon, was passiert: [Artikel] Debugger: Wie verwende ich den von Visual Studio?

Christian

Weeks of programming can save you hours of planning

C
coga Themenstarter:in
12 Beiträge seit 2011
vor 9 Jahren

Wie ich den Debugger benutzte ist mir bewusst und ich habe Ihn auch benutzt.
Ich hatte bisher kaum Berührungen mit dem Dictionary bzw. der ToDictionary Methode weswegen mir die Aussage so nicht viel bringt. Interessant ist aber das wenn ich Werte in flatList ändere, während ich debugge, ändern sich auch die entsprechenden Werte in dic - folglich nehme ich an das keine neue Instanzen der Tasks im Dictionary durch ToDictionary erstellt wurde sondern eine Liste mit Verweisen auf die Ursprünglichen (vergleichbar mit Zeigern)?

4.221 Beiträge seit 2005
vor 9 Jahren

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

C
coga Themenstarter:in
12 Beiträge seit 2011
vor 9 Jahren

Danke für die Anregung jedoch kann ich das nicht nutzten 😃 der von mir gepostet Code funktioniert, jedoch hatte ich nicht verstanden wieso - jetzt nach einigen Stunden testen und suchen hab ichs gefunden und fühle mich unglaublich dumm.

shallow copy vs. deep copy

Wie gedacht enthalten die Attribute nur Verweise aufs original weswegen das ganze funktioniert.

Thema ist erledigt! Danke trotzdem.

Hinweis von herbivore vor 9 Jahren

Ja, Klassen sind in C# immer Referenztypen und entsprechende Variablen enthalten "nur" Referenzen auf Objekte. Es geht hier also weder um shallow und erst recht nicht um deep copy, denn es werden überhaupt keine Objekte kopiert, sondern nur Referenzen zugewiesen. Attribute sind in C# allerdings was anderes. Hier geht es um Variablen.

Auch wenn du es schon selbst eingesehen hast, beachte bitte [Hinweis] Wie poste ich richtig? Punkt 1.1.1.

Thema geschlossen