Frage

Ich weiß viel über C #, aber dieses mich stumping und Google ist nicht zu helfen.

Ich habe eine IEnumerable Reihe von Objekten. Ich möchte eine Immobilie auf dem ersten setzen. Ich tue so, aber wenn ich über den Bereich der Objekte nach der Änderung aufzählen, ich sehe nicht, meine Änderung.

Hier ist ein gutes Beispiel für das Problem:

    public static void GenericCollectionModifier()
    {
        // 1, 2, 3, 4... 10
        var range = Enumerable.Range(1, 10);

        // Convert range into SubItem classes
        var items = range.Select(i => new SubItem() {Name = "foo", MagicNumber = i});

        Write(items);  // Expect to output 1,2,3,4,5,6,7,8,9,10

        // Make a change
        items.First().MagicNumber = 42;

        Write(items);  // Expect to output 42,2,3,4,5,6,7,8,9,10
        // Actual output: 1,2,3,4,5,6,7,8,9,10
    }

    public static void Write(IEnumerable<SubItem> items)
    {
        Console.WriteLine(string.Join(", ", items.Select(item => item.MagicNumber.ToString()).ToArray()));
    }

    public class SubItem
    {
       public string Name;
       public int MagicNumber;
    }

Welcher Aspekt von C # stoppt meinen „Magicnumber = 42“ Übergang von der Produktion zu sein? Gibt es eine Weise, die ich meine Veränderung zu „kleben“ bekommen, ohne etwas flippige Umwandlung zu tun zur Liste <> oder Array?

Danke! -Mike

War es hilfreich?

Lösung

Wenn Sie anrufen First () es das Ergebnis dieses Stück Code aufzählt über:

Select(i => new SubItem() {Name = "foo", MagicNumber = i});

Beachten Sie, dass die Auswahl ein fauler enumerator ist, was bedeutet, dass es nur die Auswahl tut, wenn Sie für einen Artikel von ihm fragen (und tut es alle Zeit, die Sie bitten, es). Die Ergebnisse sind nicht überall, so gespeichert, wenn Sie items.First () aufrufen Sie eine neue SubItem Instanz erhalten. Wenn Sie dann Elemente passieren zu schreiben, wird es eine ganze Reihe von neuen SubItem Instanzen -. Nicht die, die Sie vor bekommen

Wenn Sie das Ergebnis Ihrer select speichern möchten und ändern Sie es, Sie müssen etwas tun:

var items = range.Select(i => new SubItem() {Name = "foo", MagicNumber = i}).ToList();

Andere Tipps

Ich vermute, dass etwas im Hintergrund gehen. Wahrscheinlich aufgrund der IEnumerables der Tatsache kann nur einmal wiederholt werden.

Funktioniert es, wenn Sie einen Add ‚ToList ()‘ nach dem Aufruf () zu wählen, wenn sie ‚Artikel‘ zuweisen?

Das einzige, was ich denken kann, ist, dass items.First () übergibt eine Kopie SubItem zu Ihrem anstelle der Referenz, so dass, wenn Sie setzen sie die Änderung nicht durchgeführt wird.

Ich muss annehmen, dass es etwas mit IQueryable zu tun hat, nur einmal durchlaufen in der Lage zu sein. Vielleicht möchten Sie versuchen, diese zu ändern:

// Convert range into SubItem classes
var items = range.Select(i => new SubItem() {Name = "foo", MagicNumber = i});

// Convert range into SubItem classes
var items = range.Select(i => new SubItem() {Name = "foo", MagicNumber = i}).ToList();
siehe

Und wenn es irgendwelche unterschiedliche Ergebnisse.

Sie können nicht / nicht eine Sammlung durch eine enumerator ändern. Ich bin überrascht, dies keine Ausnahme werfen.

.First () ist eine Methode, nicht eine Eigenschaft. Es gibt eine neue Instanz des Objekts in der ersten Position des Enumerable.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top