myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
» Regeln
» Wie poste ich richtig?
» Forum-FAQ

Mitglieder
» Liste / Suche
» Wer ist wo online?

Ressourcen
» openbook: Visual C#
» openbook: OO
» Microsoft Docs

Team
» Kontakt
» Übersicht
» Wir über uns

» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Entwicklung » Grundlagen von C# » Kopierte List<T> Änderung in der Kopie ändert auch Oroginal
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

Kopierte List<T> Änderung in der Kopie ändert auch Oroginal

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
Emskop Emskop ist männlich
myCSharp.de-Mitglied

Dabei seit: 13.11.2020
Beiträge: 3
Entwicklungsumgebung: Visual Studio 2019
Herkunft: Emsland


Emskop ist offline

Kopierte List<T> Änderung in der Kopie ändert auch Oroginal

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ich möchte einen Index aus einer Liste kopieren und diesen dann nur in der Kopie verändern ohne das die Oroginal Liste verändert wird.

Das einzige was ich bisher gefunden haben ist der unten beschrieben weg zum kopieren der Klasse habe die unabhängigkeit der beiden Liste über den jetzt auskommentierten remove befehl getest.

Wenn ich aber LastData[0].TS mit einem anderen Wert beschreibe wird Lst_TL_Data[0].TS auch mit geändert.

Habe das ganze vorher übder den Add befehl versucht welcher aber scheinbar nur die Referenz kopiert ?

Zudem wäre es schön, nur den benötigten Datensatz über den index in die neue liste zu kopieren.

C#-Code:
public class QHMI_DATALOG_CS
    {
        public int ID { get; set; }

        public DateTime TS { get; set; }

        public string DATASOURCE { get; set; }

        public string DATATYPE { get; set; }
        public string VARNAME { get; set; }
        public string VALUE { get; set; }

        public string Quality { get; set; }

        public string MESSAGE { get; set; }

}

C#-Code:
      public void CreateLastTimestamp()
        {
            int n1 = 0;
            LastData.Clear();

            //Kopiere letzten Datensatz aus Lst_TL_Data und füge diesen in LastData ein
            if (Lst_TL_Data.Count > 0)
            {
                // Kompletten Inhalt der liste Kopieren  (nicht nur die Referenz) und in  LastData einfügen
                this.LastData = new List<QHMI_DATALOG_CS>(this.Lst_TL_Data);

                // Lösche Datensätze bis auf den letzten
                while(LastData.Count > 1 )
                {
                    LastData.RemoveAt(0);
                }
            }


            if (Lst_TL_Data.Count <= 0)
            {
                // Kompletten Inhalt der liste Kopieren  (nicht nur die Referenz) und in  LastData einfügen
                this.LastData = new List<QHMI_DATALOG_CS>(this.DataFirstPoint);

                // Lösche Datensätze bis auf den letzten
                while (LastData.Count > 1)
                {
                    LastData.RemoveAt(0);
                }
            }

          //  LastData.RemoveAt(0);


            // Soll nur den Zeitstempel der Liste LastData index 0 verändern

             LastData[0].TS = dt_Uebergabe_SQL_Ende;
        }
13.11.2020 09:51 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Alf Ator
myCSharp.de-Mitglied

avatar-586.gif


Dabei seit: 30.10.2007
Beiträge: 616
Entwicklungsumgebung: VS2005 / VS2008


Alf Ator ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo Emskop

Du hast zwar eine zweite Liste, aber die Objekte die du da rein machst, sind die selben! wie die aus der ersten List. Stichwort Reference Type.
 Google spuckt unter anderem das hier aus:  https://www.tutorialsteacher.com/csharp/csharp-value-type-and-reference-type

Ansonsten kannst du das letzte Objekt einer Liste zu einer anderen hinzufügen indem du nur das letzte der neuen Liste hinzufügts:

C#-Code:
LastData.Add(Lst_TL_Data.Last());

Übrigens ist Lst_TL_Data ein ungeschickt gewählter Name:
Heißt das Last_TL_Data oder List_TL_Data?

Ein kleiner Buchstabe, der die Lesbarkeit deutlich erhöht.


Gruß
Alf
13.11.2020 10:18 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Emskop Emskop ist männlich
myCSharp.de-Mitglied

Dabei seit: 13.11.2020
Beiträge: 3
Entwicklungsumgebung: Visual Studio 2019
Herkunft: Emsland

Themenstarter Thema begonnen von Emskop

Emskop ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Moin Alf Ator,

danke für die schnelle antwort.

Jetzt stellt sich mir die Frage ob ich die Daten auf den der Reference Type zeigt irgend wie duplizieren kann und mit einer anderen Liste verbinden kann.

Oder ob der einzige weg ist, die Daten erneut aus der SQL-Datenbank zu Laden und mit der zweiten Liste zu verknüpfen ? Damit ich beide unabhängig voneinander bearbeiten kann.

DieListen habe ich gerade umbenannt:
List_TL_Data (Oroginal Liste)
List_LastData (Liste in der ein Teil der oroginal Liste gespeichert und bearbeitet werden soll ohen die oroginal Liste zu verändern)



Gruß
Emskop
13.11.2020 13:28 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
HansFred
myCSharp.de-Mitglied

Dabei seit: 19.10.2020
Beiträge: 47


HansFred ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

was willst du machen sowas wie ein undo oder was ist der sinn?? so wie du reference types behandelst ist es ein grundlegend falsches vorgehen das du anders lösen solltest.
es macht jedenfalls keinen sinn eine liste parallel zu bearbeiten und an den sql server zu schicken
dazu sei noch gesagt das man kein DateTime in der datenbank verwenden weil das die zeitzone verliert sondern man verwendet DateTimeOffset mit datetime2 als spaltentyp

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von HansFred am 13.11.2020 13:43.

13.11.2020 13:42 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
SimpleTool
myCSharp.de-Mitglied

avatar-4145.png


Dabei seit: 23.10.2020
Beiträge: 10
Entwicklungsumgebung: VS 2019


SimpleTool ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hi,

ich hab mal eine Liste kopiert damit diese unabhängig voneinander bearbeitet werden können (2 seperate Listen, wobei die eine ein Klone ist)

C#-Code:
ListWhichIWantToCopy.ForEach((item) => { ListWhichIsNew.Add(new QHMI_DATALOG_CS(item)); });

Aber dafür muss die Klasse (hier QHMI_DATALOG_CS) dann einen Konstruktor haben z. B.

C#-Code:
public QHMI_DATALOG_CS(QHMI_DATALOG_CS cloneItem)
        {
            _interneVar1 = cloneItem.InterneVar1;
        }

Vielleicht hilft dir das weiter.
13.11.2020 14:48 Beiträge des Benutzers | zu Buddylist hinzufügen
Emskop Emskop ist männlich
myCSharp.de-Mitglied

Dabei seit: 13.11.2020
Beiträge: 3
Entwicklungsumgebung: Visual Studio 2019
Herkunft: Emsland

Themenstarter Thema begonnen von Emskop

Emskop ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

vorab ich bin noch blutiger Anfänger im Prozess Learning by doing.


mein vorhaben:

ich bekomme Anlagendaten aus einer Datenbank, Geschwindigkeiten usw. diese versuche ich momentan per C# auszuwerten Produktionszeiten, Nutzeffekt, prozentuale Stillstände und deren Gründe ...

Die Daten werden nur bei Zustandsänderungen in die DB geschriebn.

Daher lade ich mir die Daten für einen gewissen Zeitraum und muss den ersten und den letzten Datenpunkt ergänzen. Um sauber rechnen zu können.

Der letzte Datenpunkt innerhalb des Zeitraumes der SQL Datenbak entspricht dem Zustand des Endzeitpunktes meiner Auswertung daher wollte ich diesen in eine seperate Liste kopieren und den Zeitstempel ändern um danach beide Listen zusammen zu führen.

Und dann mit der Zusammengeführetn Liste zu Arbeiten.

Ich bin das Problem jetzt umganagen indem ich mir nur den benötigenten Datensatz aus der DB in eine neu erstellte Liste Lade.


cloneItem scheint der richtige weg zu sein allerdings möchte ich an der Klasse QHMI_DATALOG_CS momentan ungern was ändern, da diese an vielen stellen verwendet wird.

Danke für die schnellen Antworten.
18.11.2020 08:12 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
SimpleTool
myCSharp.de-Mitglied

avatar-4145.png


Dabei seit: 23.10.2020
Beiträge: 10
Entwicklungsumgebung: VS 2019


SimpleTool ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zur Ergänzung noch die Info bzgl.:

Zitat:
[...]allerdings möchte ich an der Klasse QHMI_DATALOG_CS momentan ungern was ändern, da diese an vielen stellen verwendet wird.

Wenn du in deiner Klasse den alten Konstruktor nicht löscht oder veränderst, dürfte es bei den anderen Stellen im Code, wo du diesen Konstruktor schon benutzt, nichts ändern. Bzw. du hast ihn noch nicht implementiert daher würde ich den dann noch hinzuschreiben.

Spontan würde ich die Klasse wie folgt ändern um so auch an anderen Stellen noch das alte Verhalten zu gewährleisten:

C#-Code:
    public class QHMI_DATALOG_CS
    {
        public int ID { get; set; }

        public DateTime TS { get; set; }

        public string DATASOURCE { get; set; }

        public string DATATYPE { get; set; }
        public string VARNAME { get; set; }
        public string VALUE { get; set; }

        public string Quality { get; set; }

        public string MESSAGE { get; set; }

        /// <summary>
        /// Default Konstruktor der für die  anderen Programmstellen dann benutzt wird
        /// </summary>
        public QHMI_DATALOG_CS()
        {

        }
        /// <summary>
        /// Konstruktor um die Liste mit QHMI_DATALOG_CS zu klonen, Item für Item mit ForEach
        /// </summary>
        /// <param name="cloneItem">Item das ich kopieren möchte (ohne Referenz)</param>
        public QHMI_DATALOG_CS(QHMI_DATALOG_CS cloneItem) :this()
        {
            ID = cloneItem.ID;
            TS = DateTime.Parse(cloneItem.TS.ToString()); // DateTime ist glaube ich ein Referenztyp, daher würde ich in String wandeln und neues Objekt daraus machen, müsste man wenn man das nicht will einfach testen
            DATASOURCE = cloneItem.DATASOURCE;
            DATATYPE = cloneItem.DATATYPE;
            VARNAME = cloneItem.VARNAME;
            VALUE = cloneItem.VALUE;
            Quality = cloneItem.Quality;
            MESSAGE = cloneItem.MESSAGE;
        }

    }
20.11.2020 10:50 Beiträge des Benutzers | zu Buddylist hinzufügen
Th69
myCSharp.de-Poweruser/ Experte

avatar-2578.jpg


Dabei seit: 01.04.2008
Beiträge: 3.810
Entwicklungsumgebung: Visual Studio 2015/17


Th69 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

@SimpleTool:  DateTime ist eine Struktur, also ein Wertetyp.
Daher reicht:

C#-Code:
TS = cloneItem.TS;
20.11.2020 13:20 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
MrSparkle MrSparkle ist männlich
myCSharp.de-Team

avatar-2159.gif


Dabei seit: 16.05.2006
Beiträge: 5.572
Herkunft: Leipzig


MrSparkle ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ansonsten gibt es auch die  MemberwiseClone-Methode
20.11.2020 14:32 Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum
Antwort erstellen


© Copyright 2003-2020 myCSharp.de-Team | Impressum | Datenschutz | Alle Rechte vorbehalten. | Dieses Portal verwendet zum korrekten Betrieb Cookies. 06.12.2020 02:58