C# memcpy 等效

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/510971/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 06:15:15  来源:igfitidea点击:

C# memcpy equivalent

c#serializationcopying

提问by Adi Barda

I have 2 objects from the same type and i would like to shallow copy one state to the other. In C++ i have memcpy which is great. How can i do it in C#? The MemberwiseClone() is not good enough because it creates & returns a new object and i like to copy to an existing object. I thought of using reflection but i'm afraid it will be too slow for production code. I also thought of using one of the .Net serializers but i think they also create object rather than setting an existing one.

我有 2 个相同类型的对象,我想将一种状态浅复制到另一种状态。在 C++ 中,我有 memcpy,这很棒。我怎样才能在 C# 中做到这一点?MemberwiseClone() 不够好,因为它创建并返回一个新对象,我喜欢复制到现有对象。我想过使用反射,但恐怕它对于生产代码来说太慢了。我也想过使用 .Net 序列化程序之一,但我认为它们也创建对象而不是设置现有的对象。

My Use Case:

我的用例:

I have a template object (class not struct) which needs to be updated by one of its instances (objects made of this template)

我有一个模板对象(类不是结构),它需要由它的一个实例(由这个模板组成的对象)更新

Any ideas?

有任何想法吗?

采纳答案by peterchen

[edit] regarding your clarification: As I understand, you have N objects, each has a (direct) reference to the template object. You want to write back to the template so all objects "see" these changes.

[编辑] 关于您的澄清:据我所知,您有 N 个对象,每个对象都有一个(直接)引用模板对象。您想写回模板,以便所有对象“看到”这些更改。

Suggestion: imlement a template broker.

建议:实现一个模板代理。

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

Instead of passing the template, pass the template provider to the objects.

不是传递模板,而是将模板提供程序传递给对象。

to simplyfy the syntax in the components, you can add a (private/internal?) property

为了简化组件中的语法,您可以添加一个(私有/内部?)属性

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

The template provider also simplifies locking in multithreaded scenarios.

模板提供程序还简化了多线程场景中的锁定。



In short, no way unless you do it yourself. But why not create a new object if you override all properties anyway?

总之,除非你自己做,否则没有办法。但是,如果您无论如何都要覆盖所有属性,为什么不创建一个新对象呢?

memcopyand similar low level constructs are not supported since they undermine guarantees made by the environment.

memcopy并且不支持类似的低级构造,因为它们破坏了环境做出的保证。

A shallow copy for structs is made by assignment. For classes, MemberwiseCloneis the method to do that - but as you say that creates a new object.

结构的浅拷贝是通过赋值进行的。对于类,MemberwiseClone是这样做的方法 - 但正如你所说的那样创建一个新对象。

There is no built in way for that, and as it potentially breaks encapsulation it should be used with care anyway.

没有内置的方法,因为它可能会破坏封装,所以无论如何都应该小心使用。

You could build a generic routine using reflection, but whether it works or not depends on the class itself. And yes, ti will be comparedly slow.

您可以使用反射构建一个通用例程,但它是否有效取决于类本身。是的,ti 会比较慢。

What's left is supporting it by a custom interface. You can provide a generic "Shallow Copy" routine that checks for the interface and uses that, and falls back to reflection when it doesn't. This makes the functionality available generally, and you can optimize the classes for which performance matters later.

剩下的就是通过自定义界面来支持它。您可以提供一个通用的“浅拷贝”例程来检查接口并使用它,并在没有时回退到反射。这使得功能普遍可用,并且您可以优化稍后对性能很重要的类。

回答by Quassnoi

In C#(and in C++too), there is no difference between "new object" and "a copy of existing object" as long as all their members equal to each other.

C#(以及C++同样)中,只要“新对象”和“现有对象的副本”的所有成员彼此相等,就没有区别。

Given:

鉴于:

Int32 a = 5;

, both operations:

, 两个操作:

Int32 b = 5;
Int32 b = a;

yield the same result.

产生相同的结果。

As stated in MSDN reference:

正如MSDN 参考中所述

The MemberwiseClone method creates a shallow copy by creating a new object, and then copying the nonstatic fields of the current object to the new object.

If a field is a value type, a bit-by-bit copy of the field is performed.

If a field is a reference type, the reference is copied but the referred object is not; therefore, the original object and its clone refer to the same object.

MemberwiseClone 方法通过创建一个新对象,然后将当前对象的非静态字段复制到新对象来创建浅拷贝。

如果字段是值类型,则执行该字段的逐位复制。

如果字段是引用类型,则复制引用但不复制引用的对象;因此,原始对象和它的克隆引用同一个对象。

, i.e. it does just the same as memcpy()in C++

,也就是说,它不只是同memcpy()C++

回答by Sergio

I guess you could just do something like:

我想你可以这样做:

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

This will create a new object inside the MemberwiseClone method an make the B object reference it. I guess it serves your purposes.

这将在 MemberwiseClone 方法内创建一个新对象,并使 B 对象引用它。我想它符合你的目的。

回答by Adi Barda

I cannot use a newly created object because i like the templateobject to be changed according to the state of one of its instances (i.e instance made of that template)

我不能使用新创建的对象,因为我喜欢根据其实例之一的状态(即由该模板组成的实例)更改模板对象

回答by Adi Barda

When i think about it - it's very interesting to look at the code of the MemberWiseClone() method implementation and see how Microsoft solved my question.

当我想到它时 - 查看 MemberWiseClone() 方法实现的代码并了解 Microsoft 如何解决我的问题非常有趣。

回答by Konrad Rudolph

Assignment of one struct to another, for all intents and purposes, works exactlylike memcpyin C++ on POD objects.

出于所有意图和目的,将一个结构体分配给另一个结构体的工作方式与C++ 中 POD 对象的工作方式完全相同memcpy

If you feel that this doesn't apply in your situation then I can assure you that your C++ code was not standard-conforming (i.e., contained bugs in the form of undefined behaviour). Please specify (in the question) what effect you want to achieve. This will be more useful than talking about replicating undefined behaviour in another language.

如果您觉得这不适用于您的情况,那么我可以向您保证,您的 C++ 代码不符合标准(即,包含未定义行为形式的错误)。请指定(在问题中)您想要达到的效果。这比谈论用另一种语言复制未定义的行为更有用。

回答by Michael Buen

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
        }
    }
}

回答by Michael Buen

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

        }
    }
}