我具有由相同类型2个对象和我想浅拷贝一个状态到另一个。在C ++中,我有memcpy的这是伟大的。我如何能做到这一点在C#中?在MemberwiseClone()是不够的,因为它创建和返回一个新的对象,我想复制到现有的对象。我想用反射,但恐怕这将是生产代码太慢。我还想到使用.net串行器中的一个的,但我认为它们还创建对象,而不是设置一个现有的

我的用例:

我有一个模板对象(类不是struct)需要由它的实例之一(对象所做的该模板的)进行更新

任何想法?

有帮助吗?

解决方案

[编辑]关于您澄清: 据我了解,你有N个对象,每个人都有一个(直接)参考模板对象。你想的那么所有对象“看到”这些变化写回的模板。

建议:imlement模板经纪人

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是做到这一点的方法 - 但是就像你说的,创建一个新的对象。

有没有内置在这种方式,并且因为它可能会中断封装它应谨慎反正使用。

您可以建立使用反射通用的套路,而是它是否有效与否取决于类本身。是的,TI将comparedly慢。

剩下的就是通过自定义接口,支持它。你可以提供一个通用的“浅拷贝”例程检查接口并使用,而当它不回落到反射。这使得一般可用的功能,并且可以优化其性能以后重要的类。

其他提示

C#(以及在C++太),有“新的对象”和“现有对象的副本”之间没有差别,只要它们的所有成员彼此相等。

假设:

Int32 a = 5;

,这两个操作:

Int32 b = 5;
Int32 b = a;

产生相同的结果。

MSDN参考表示:

  

在MemberwiseClone方法通过创建一个新对象,然后复制当前对象的非静态字段到新对象创建一个浅表副本。

     

如果一个字段是值类型,位逐位字段的拷贝被执行。

     

如果一个字段是一个引用类型,参考被复制,但称为对象不是;因此,原来的对象及其克隆指代相同的对象。

,即,它不只是一样memcpy() C++

我猜你可能只是这样做:

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

这将创建MemberwiseClone方法内的新对象的使B对象引用它。我想这成为你的目的。

一个结构到另一的分配,对于所有意图和目的,效果准确像上POD对象memcpy在C ++中。

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

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

        }
    }
}

我不能使用新创建的对象,因为我喜欢的模板对象,以根据它的实例中的一个(即例如由该模板的)的状态来改变

当我想它 - 这是非常有趣的看MemberWiseClone()方法执行的代码,看看微软是如何解决我的问题。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top