如何创建数据模型的副本

本文关键字:数据模型 副本 创建 何创建 | 更新日期: 2023-09-27 18:10:39

在我的程序中,我试图复制一个数据模型,以便我可以将其设置为另一个用户控件的数据模型。

到目前为止,我已经尝试将新的数据模型设置为我想要复制的数据模型,但所做的一切都是将两个用户控件瞄准相同的数据模型。

我所做的一个例子:

newUserControl.NewDataModel = oldUserControl.OldDataModel;

如何复制数据模型,以便将其设置为另一个用户控件的数据模型上下文,而不使UCs针对相同的数据模型?

如何创建数据模型的副本

实现此目的的一种方法是创建一个泛型扩展方法。这允许你克隆任何对象,无论其类型如何,只要它是可序列化的(具有' serializable '属性)。

public static class ObjectExtensions
{    
    public static T Clone<T>(this T source)
    {
            if (!typeof(T).IsSerializable)
            {
                throw new ArgumentException("This type must be serializable.", "source");
            }
            if (Object.ReferenceEquals(source, null))
                return default(T);
            IFormatter formatter = new BinaryFormatter();
            Stream stream = new MemoryStream();
            using (stream)
            {
                formatter.Serialize(stream, source);
                stream.Seek(0, SeekOrigin.Begin);
                return (T)formatter.Deserialize(stream);
            }
     }
}

正如@TroelsLarsen所提到的,存在复制事件订阅的风险。为了避免这种情况,您可以将NonSerializedAttribute添加到不希望序列化的字段中。以下是带有示例的MSDN文档。

那么你就像这样使用它:

newUserControl.DataModel = oldDataUserControl.DataModel.Clone();

我要做的是实现一个消息传递基础设施。这是我以前用过的,它让事情变得简单多了。它本质上是一个事件你可以在一个控件上设置然后在另一个控件上订阅该事件并使用该事件来回传递内容:

http://mvvmlight.codeplex.com/

在创建新DataModel的类上创建Clone()方法,并复制所需的属性。

public DataModel Clone() {
    return new DataModel() {
        PropertyA = this.PropertyA,
        PropertyB = this.PropertyB,
        //etc.
    }
}
//OR - Without a clone method:
newUserControl.NewDataModel = new DataModel()
{
    PropertyA = oldUserControl.OldDataModel.PropertyA,
    PropertyB = oldUserControl.OldDataModel.PropertyB,
    //etc
}

阐述:这不起作用的原因是,简单地将NewDataModel赋值给OldDataModal意味着只复制对该对象的引用。换句话说,您没有创建一个新的DataModel,您只是将两个属性指向同一个实例。

通过创建Clone()方法,您正在创建一个与旧数据模型相同的新数据模型,但是在内存中的不同位置。