Liste wird immer referenziert.

  • C#

Es gibt 2 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Liste wird immer referenziert.

    Ich nutze den Code von Verschachteltes Grouping - LINQ.
    Doch irgendwie, wird automatisch durch das Gruppieren auch die Ausgangsliste verändert.
    Folgendes Beispiel.

    C#-Quellcode

    1. // Demo Elemente
    2. IEnumerable<Item> collection = new List<Item>()
    3. {
    4. new Item() {ID = 1, Category = 1, Name = "Test", Price = 1.0f},
    5. new Item() {ID = 1, Category = 1, Name = "Test", Price = 2.0f},
    6. new Item() {ID = 1, Category = 1, Name = "Test", Price = 2.0f},
    7. new Item() {ID = 1, Category = 2, Name = "Test", Price = 2.0f},
    8. new Item() {ID = 1, Category = 2, Name = "Test", Price = 2.0f},
    9. new Item() {ID = 2, Category = 1, Name = "Abc", Price = 3.0f},
    10. new Item() {ID = 2, Category = 1, Name = "Abc", Price = 4.0f},
    11. new Item() {ID = 2, Category = 3, Name = "Abc", Price = 2.0f},
    12. };
    13. var groups = new List<GroupedItem>();
    14. List<Item> items = new List<Item>(collection);
    15. foreach (var grID in from itm in items group itm by itm.ID)
    16. {
    17. var cats = new List<Item>();
    18. foreach (var grCat in from itm in grID group itm by itm.Category)
    19. {
    20. var cat = grCat.First();
    21. cat.Price = grCat.Sum(c => c.Price);
    22. cats.Add(cat);
    23. }
    24. var gi = new GroupedItem() { ID = grID.Key, Name = grID.First().Name, Childs = cats, Price = cats.Sum(itm => itm.Price) };
    25. groups.Add(gi);
    26. }


    Schaut man sich jetzt nach der Gruppierung collection an, sind die Werte verändert.
    Aber warum? Ich nutze doch den Kopierkonstruktor der Liste.
    .ToList() klappt ebenso wenig.


    Weiß da jemand warum das so ist, und noch besser, wie ich das Problem lösen kann? :)

    Klassen

    C#-Quellcode

    1. public class Item
    2. {
    3. public int ID { get; set; }
    4. public int Category { get; set; }
    5. public string Name { get; set; }
    6. public float Price { get; set; }
    7. }
    8. public class GroupedItem
    9. {
    10. public int ID { get; set; }
    11. public string Name { get; set; }
    12. public float Price { get; set; }
    13. public IEnumerable<Item> Childs { get; set; }
    14. }


    Edit: Item ist class und nicht struct. Wenn ich das änder, dann klappt es.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „LaMiy“ ()

    Was ist mit probier mal ne Clone-Extension für List<T> zu schreiben, mit MemoryStream und so. Und dann die zu nutzen anstatt des Konstruktors.
    Vllt macht der das ja nicht richitg.
    »There's no need to "teach" atheism. It's the natural result of education without indoctrination.« — Ricky Gervais

    LaMiy schrieb:

    Weiß da jemand warum das so ist,
    Naja, es wird tw. mit den Original-Items gearbeitet.
    Aus denen werden ja Gruppen gebildet, und Unter-Gruppen.
    Und in #22 wird das erste Item einer Untergruppe hergenommen, um da die Price-Summe reinzuschreiben, und dann kommt es in die Ausgabe.
    Es ist aber nachwievor das erste Item dieser Gruppe, die aus der Ausgangsliste gebildet wurde., und daher hat diese Item halt einen geänderten Price.

    Jo, ist nicht gut, da solltest du ein neues Item für hernehmen. Vom vorherigen Item kannste ja alle Properties übernehmen, bis auf den Price - der wird ja im folgenden erst noch aufsummiert.

    Also dass du da jetzt nicht anfängst, iwas komisches zu machen, sag ich mal weiter vor:

    C#-Quellcode

    1. IEnumerable<Item> collection = new List<Item>()
    2. {
    3. new Item() {ID = 1, Category = 1, Name = "Test", Price = 1.0f},
    4. new Item() {ID = 1, Category = 1, Name = "Test", Price = 2.0f},
    5. new Item() {ID = 1, Category = 1, Name = "Test", Price = 2.0f},
    6. new Item() {ID = 1, Category = 2, Name = "Test", Price = 2.0f},
    7. new Item() {ID = 1, Category = 2, Name = "Test", Price = 2.0f},
    8. new Item() {ID = 2, Category = 1, Name = "Abc", Price = 3.0f},
    9. new Item() {ID = 2, Category = 1, Name = "Abc", Price = 4.0f},
    10. new Item() {ID = 2, Category = 3, Name = "Abc", Price = 2.0f},
    11. };
    12. var groups = new List<GroupedItem>();
    13. foreach (var grID in from itm in collection group itm by itm.ID) {
    14. var cats = new List<Item>();
    15. foreach (var grCat in from itm in grID group itm by itm.Category) {
    16. var firstCat=grCat.First();
    17. var cat = new Item { Category = firstCat.Category, ID = firstCat.ID, Name = firstCat.Name };
    18. cat.Price = grCat.Sum(c => c.Price);
    19. cats.Add(cat);
    20. }
    21. var gi = new GroupedItem() { ID = grID.Key, Name = grID.First().Name, Childs = cats, Price = cats.Sum(itm => itm.Price) };
    22. groups.Add(gi);
    23. }
    (Insbesondere die Items von class auf struct umzuändern dürfte unerwünschte Folgen haben)