在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);
}
克隆/复制对象时,您可以简单地克隆/复制它们。序列化是非常昂贵的,尤其是在不考虑性能的情况下实现时(您可以在这个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提出了一个有效的观点,他建议用数据模型类代替完整的数据表。