Frage

Ich habe 2 Objekte vom gleichen Typ und i auf flache Kopie einem Zustand zum anderen möchten. In C ++ Ich habe Memcpy was ausgezeichnet ist. Wie kann ich tun es in C #? Die MemberwiseClone () ist nicht gut genug, weil es schafft und gibt ein neues Objekt und Ich mag an ein bestehendes Objekt kopieren. Ich dachte, die Reflexion mit, aber ich habe Angst, daß es für die Produktion Code zu langsam sein wird. Ich dachte auch, eine des .Net Serializer verwenden, aber ich denke, sie schaffen auch Objekt, anstatt eine vorhandene Einstellung.

Meine Use Case:

Ich habe ein Template-Objekt (Klasse nicht struct), die von einem seiner Instanzen aktualisiert werden muss (Objekte dieser Vorlage gemacht)

Irgendwelche Ideen?

War es hilfreich?

Lösung

[Bearbeiten] in Bezug auf Ihre Klarstellung: Wie ich verstehe, Sie N-Objekte hat, jeder hat einen (direkten) Verweis auf das Vorlagenobjekt. Sie wollen zurück in die Vorlage schreiben, so dass alle Objekte „sehen“ diese Änderungen.

Vorschlag: imlement eine Vorlage broker

.
class TemplateProvider
{
   public MyData Template { get; set; }
}

Statt die Vorlage vorbei, die Vorlage Anbieter auf die Objekte übergeben.

die Syntax in den Komponenten simplyfy, können Sie eine (privat / intern?) Hinzufügen Eigenschaft

MyData Template { get { return m_templateProvider.Template; } }
void UpdateTemplate() { m_templateProvider.Template = 
                            (MyData) this.MemberwiseClone(); }

Die Vorlage Anbieter vereinfacht auch in Multi-Thread-Szenarien sperren.


Kurz gesagt, auf keinen Fall, wenn Sie es selbst tun. Aber warum nicht ein neues Objekt erstellen, wenn Sie alle Eigenschaften ohnehin außer Kraft setzen?

memcopy und ähnliche niedriges Niveau Konstrukte werden nicht unterstützt, da sie von der Umwelt gemacht Garantien untergraben.

Eine flache Kopie für structs wird durch Zuordnung vorgenommen. Für Klassen, ist MemberwiseClone das Verfahren, das zu tun - aber wie Sie sagen, dass ein neues Objekt erstellt.

Es gibt keine in Art und Weise für das gebaut, und wie es möglicherweise Verkapselung bricht es sollte auf jeden Fall mit Vorsicht verwendet werden.

Sie können eine generische Routine mit Reflexion, bauen aber, ob es funktioniert oder nicht, hängt von der Klasse selbst. Und ja, ti wird comparedly langsam.

Was bleibt, ist es durch eine benutzerdefinierte Schnittstelle zu unterstützen. Sie können eine generische „Shallow Copy“ Routine bereitstellen, die für die Schnittstelle überprüft und verwendet diese, und fällt zurück auf Reflexion, wenn dies nicht der Fall. Dies macht die Funktionalität allgemein verfügbar, und Sie können die Klassen optimieren, für die Leistung später ankommt.

Andere Tipps

In C# (und in C++ auch), gibt es keinen Unterschied zwischen „neues Objekt“ und „eine Kopie des vorhandenen Objekts“, solange alle Mitglieder gleich zueinander sind.

Gegeben:

Int32 a = 5;

, beide Operationen:

Int32 b = 5;
Int32 b = a;

das gleiche Ergebnis liefern.

Wie bereits erwähnt in MSDN Referenz :

  

Die MemberwiseClone-Methode erstellt eine flache Kopie durch ein neues Objekt erstellen, und dann das Kopieren der nicht statischen Felder des aktuellen Objekts auf das neue Objekt.

     

Wenn ein Feld ein Werttyp ist, eine Bit-für-Bit Kopie des Feldes durchgeführt wird.

     

Wenn ein Feld ein Referenztyp ist, die Referenz kopiert wird, aber das genannte Objekt ist nicht; daher das ursprüngliche Objekt und sein Klon auf das gleiche Objekt beziehen.

, das heißt, es tut genau das gleiche wie memcpy() in C++

Ich denke, man nur etwas tun könnte, wie:

YourObjectType A = new YourObjectType();
YourObjectType B = a.MemberwiseClone();

Damit wird ein neues Objekt innerhalb der MemberwiseClone-Methode erstellen eine des B-Objekt auf sie verweisen machen. Ich denke, es dient Ihre Zwecke.

Zuordnung von einer Struktur in einer anderen, für alle Absichten und Zwecke, funktioniert genau wie memcpy in C ++ auf POD-Objekten.

Wenn Sie das Gefühl, dass dies nicht in Ihrer Situation gilt dann kann ich Ihnen versichern, dass Ihre C ++ Code war nicht normkonforme (das heißt, enthalten Fehler in Form von undefinierten Verhalten). Bitte geben ( in der Frage ), welchen Effekt Sie erreichen wollen. Dies wird nützlicher sein als redet über undefiniertes Verhalten in einer anderen Sprache zu replizieren.

namespace WindowsFormsApplication7
{

    [Serializable] // just put this in your class
    class Mate
    {
        public string SomeProperty { get; set; }
    }

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();


            var mA = new Mate();
            mA.SomeProperty = "Hey";

            var vf = new BinaryFormatter();
            var ns = new MemoryStream();
            vf.Serialize(ns, mA);
            byte[] vytes = ns.ToArray();


            var vfx = new BinaryFormatter();
            var nsx = new MemoryStream();            
            nsx.Write(vytes, 0, vytes.Length);
            nsx.Seek(0, 0);
            var mB = (Mate)vfx.Deserialize(nsx);

            mA.SomeProperty = "Yo";

            MessageBox.Show(mA.SomeProperty); // Yo
            MessageBox.Show(mB.SomeProperty); // Hey
        }
    }
}
namespace WindowsFormsApplication7
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            var dt = new DataTable();
            dt.Columns.Add("lastname", typeof(string));
            dt.Columns.Add("firstname", typeof(string));

            dt.Rows.Add("lennon", "john");
            dt.Rows.Add("mccartney", "paul");


            var ms = new MemoryStream();
            var bf = new BinaryFormatter();
            bf.Serialize(ms, dt);
            byte[] bytes = ms.ToArray();



            var bfx = new BinaryFormatter();
            var msx = new MemoryStream();
            msx.Write(bytes, 0, bytes.Length);
            msx.Seek(0, 0);


            // doesn't just copy reference, copy all contents
            var dtx = (DataTable)bfx.Deserialize(msx);


            dtx.Rows[0]["lastname"] = "Ono";


            // just copy reference
            var dty = dt;

            dty.Rows[0]["lastname"] = "Winston";

            MessageBox.Show(dt.Rows[0]["lastname"].ToString()); // Winston
            MessageBox.Show(dtx.Rows[0]["lastname"].ToString()); // Ono
            MessageBox.Show(dty.Rows[0]["lastname"].ToString()); // Winston

        }
    }
}

Ich kann nicht ein neu erstelltes Objekt verwenden, weil ich die mag Vorlage Objekt geändert in den Zustand eines seiner Instanzen nach werden (das heißt Instanz dieser Vorlage gemacht)

Wenn ich darüber nachdenke - es ist sehr interessant, auf dem Code des MemberwiseClone () -Methode Umsetzung zu schauen und sehen, wie Microsoft meine Frage gelöst

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