В C# функции memcpy эквивалент

У меня есть 2 объекта одного типа, и я хотел бы мелко скопировать одно состояние в другое. В C++ у меня есть memcpy, что здорово. Как я могу сделать это в C#? MemberwiseClone () недостаточно хорош, потому что он создает и возвращает новый объект, и мне нравится копировать в существующий объект. Я думал использовать reflection, но боюсь, что он будет слишком медленным для производственного кода. Я также думал об использовании одного из сериализаторов .Net, но я думаю, что они также создают объект, а не устанавливают существующий один.

Мой Пример:

У меня есть объект шаблона (class not struct), который должен быть обновлен одним из его экземпляров (объекты, сделанные из этого шаблона)

какие идеи?

8 ответов


[edit] относительно вашего разъяснения: Как я понимаю, у вас есть N объектов, каждый из которых имеет (прямую) ссылку на объект шаблона. Вы хотите записать обратно в шаблон, чтобы все объекты "видели" эти изменения.

предложение: реализации шаблона брокера.

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

вместо передачи шаблона передайте поставщику шаблонов объекты.

в simplyfy синтаксис в компоненты, можно добавить (частный/внутренний?) собственность

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

поставщик шаблонов также упрощает блокировку в многопоточных сценариях.


короче говоря, ни в коем случае, если вы не сделаете это сами. Но почему бы не создать новый объект, если вы все равно переопределяете все свойства?

memcopy и подобные низкоуровневые конструкции не поддержаны в виду того что они подрывают гарантии сделанные окружающей средой.

мелкая копия для структур производится по назначению. Для занятий,MemberwiseClone - это способ сделать это-но, как вы говорите, это создает новый объект.

для этого нет встроенного способа,и поскольку он потенциально нарушает инкапсуляцию, его следует использовать с осторожностью.

вы можете создать общую процедуру с помощью отражения, но работает ли она или нет, зависит от самого класса. И да, ти будет comparedly медленно.

то, что осталось, поддерживает его с помощью пользовательского интерфейса. Вы можете предоставить общую процедуру "мелкой копии", которая проверяет интерфейс и использует это и возвращается к размышлениям, когда это не так. Это делает функциональность доступной в целом, и вы можете оптимизировать классы, для которых производительность имеет значение позже.


на C#C++ тоже), нет никакой разницы между" новым объектом "и" копией существующего объекта", пока все их члены равны друг другу.

дано:

Int32 a = 5;

, оба действия:

Int32 b = 5;
Int32 b = a;

дайте тот же результат.

как говорится в MSDN reference:

метод MemberwiseClone создает неглубокую копию путем создания нового объекта, а затем копирования нестатических полей текущего объекта к новому объекту.

если поле имеет тип значения, выполняется его побитовая копия.

если поле является ссылочным типом, ссылка копируется, но указанный объект-нет; поэтому исходный объект и его клон ссылаются на один и тот же объект.

, т. е. он делает то же самое, что и memcpy() на C++


Я думаю, вы могли бы просто сделать что-то вроде:

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

Это создаст новый объект внутри метода MemberwiseClone и сделает ссылку на объект B. Полагаю, это служит вашим целям.


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

        }
    }
}

Я не могу использовать вновь созданный объект, потому что мне нравится шаблон объект должен быть изменен в соответствии с состоянием одного из его экземпляров (i.e экземпляр, сделанный из этого шаблона)


когда я думаю об этом-очень интересно посмотреть на код реализации метода MemberWiseClone() и посмотреть, как Microsoft решила мой вопрос.


назначение одной структуры другой, для всех намерений и целей, работает ровно как memcpy в C++ на объектах POD.

Если вы чувствуете, что это не относится к вашей ситуации, я могу заверить вас, что ваш код C++ не соответствовал стандарту (т. е. содержал ошибки в виде неопределенного поведения). Пожалуйста, укажите (на вопрос) какой эффект вы хотите достичь. Это будет более полезно, чем говорить о репликации неопределено поведение на другом языке.