在c#中克隆具有DataTable和其他对象属性的复杂对象

本文关键字:对象 其他 属性 复杂 DataTable | 更新日期: 2023-09-27 18:06:48

我想深度复制我复杂的c#对象的DataTable作为属性。抛出的错误是"表SalesData不属于这个数据集"。

这是我的c#对象:
public class Foo
{
    public VehicleDetails VehicleDetails { get; set; }
    public VehicleCondition VehicleCondition { get; set; }
    public string Zipcode { get; set; }
    public string StateCode { get; set; }
    public DataTable SalesData { get; set; }
    public DataTable OtherDataTable { get; set; }
}

我使用了以下代码来克隆对象:

  public static T CloneFullObject<T>(T i)
    {
        if (Object.ReferenceEquals(i, null)) return default(T);
        var x = new XmlSerializer(i.GetType());
        using (var m = new MemoryStream())
        {
            x.Serialize(m, i);
            m.Seek(0, SeekOrigin.Begin);
            return (T)x.Deserialize(m);
        }
    }

我创建的对象为:

   Foo foo = new Foo();
   VehicleDetails vehicleDetail = new VehicleDetails();
   // Fill vehicleDetail object
    VehicleCondition vehicleCondition = new VehicleCondition ();
   // Fill vehicleCondition object
   foo.VehicleDetails = vehicleDetail;
   foo.VehicleCondition = vehicleCondition;
   DataTable salesData = getDataTable();
   salesData.TableName = "salesData";
   foo.SalesData = salesData;
   DataTable otherData = getDataTable();
   salesData.TableName = "otherData";
   foo.OtherDataTable = salesData;

下面的代码抛出错误:

       System.InvalidOperationException: There was an error generating the XML document. ---> System.ArgumentException: Table salesData does not belong to this DataSet.

Foo clonefullObject = clonefullObject (Foo);

如果我在克隆对象之前错过了什么,请帮助。

注意:两个Datatable都有value且不能为空

编辑:类Foo有一些复杂的属性,如:

    private int _mileage;
    public void SetMileage(int mileage) { _mileage = mileage; }
    private int _expectedMileage;
    public void SetExpectedMileage(int mileage) { _expectedMileage =       mileage; }
    public int GetMileage(bool flag)
    {
        return (flag)
                   ? _mileage
                   : Math.Max(_mileage, _expectedMileage);
    }

在c#中克隆具有DataTable和其他对象属性的复杂对象

克隆/复制对象时,您可以简单地克隆/复制它们。序列化是非常昂贵的,尤其是在不考虑性能的情况下实现时(您可以在这个SE问题中了解更多信息)。

然而,序列化并不是你真正的问题,复制带结构和数据的DataTable才是。看起来你的问题并不是你的问题,你解决问题的方法才是你的问题。DataTable.Copy()完成所有这些。

那么该怎么做呢?好吧,合适的呢?

适当的方法之一是实现一个可容忍的接口。它有点笨拙,因为返回类型是object。通过在子类上实现它,你可以更深入地链接它。我在样本中使用as进行强制转换,考虑到它不会在类型不匹配时产生异常。(通常你可以阅读更多关于旧SE问题的内容)。您可能希望,也可能不希望在DataTables的故障状态(null)上生成异常。

public class Foo : ICloneable
{
    //some fields....
    private int _Bar; //private field
    public void SetBar(int value) { _Bar = value; } //Field setter        
    public object Clone()
    {
        var result = new Foo()
        {
            _Bar = _Bar, // private members are accessible from their scope, even when object is different
            Zipcode = Zipcode,
            StateCode = StateCode,
            SalesData = SalesData== null ? null : SalesData.Copy(),
            OtherDataTable = OtherDataTable == null ? null : OtherDataTable.Copy(),
            VehicleDetails = VehicleDetails.Clone() as VehicleDetails,
            VehicleCondition = VehicleCondition.Clone() as VehicleCondition,
        };
        // alternatively you can call setter methods
        result.SetBar(_Bar);
        return result;
    }
}

指出:

你应该努力以更好的风格创建对象,例如使用Factory或至少使用对象初始化器或构造函数。

@SergeyBerezovskiy提出了一个有效的观点,他建议用数据模型类代替完整的数据表。