最近在寫程序的時候,碰到了一個 DataTable.Clone() 的問題,描述如下:
程序中,需要傳入一個DataTable,並且,希望返回該表中一些修改好的數據行,程序代碼如下:
public DataTable ChangeTable(DataTable dtSoc,DataTable dtTemp)
{
dtTemp=dtSoc.Clone();
foreach(DataRow row in dtSco.Rows)
{
if(row["Name"]=="mingzi")
{
row["Adress"]="111";
dtTemp.importRow(row);//這個函數忘記叫麼子了
}
}
return dtTemp;
}
本以爲該函數能夠正確的返回修改的值,實際上,返回的結果好像是null,然後,自己對DataTable的類型有點疑惑,呵呵,因爲參數傳的是DataTable,是一個引用類型,函數裏面,對它的任一修改,都回返回。實際上,由於程序裏面有了DataTable.Clone()這個方法,使得結果不如自己希望的。
DataTable.Clone(),對象的拷貝,在c#裏面,有淺拷貝和深拷貝的區別,淺拷貝,只拷貝對象的數據,對對象的修改,都將影響到原對象。深拷貝,會從新分配一個地址,保存一個對象,對新對象的修改,不會影響到原有程序。
按照程序的結果,DataTable.Clone() 應該是深拷貝。
附上微軟 該函數的方法:
{
DataTable clone = (DataTable) Activator.CreateInstance(base.GetType());
if (clone.Columns.Count > 0)
{
clone.Reset();
}
return this.CloneTo(clone, cloneDS);
}
private DataTable CloneTo(DataTable clone, DataSet cloneDS)
{
clone.tableName = this.tableName;
clone.tableNamespace = this.tableNamespace;
clone.tablePrefix = this.tablePrefix;
clone.fNestedInDataset = this.fNestedInDataset;
clone.caseSensitive = this.caseSensitive;
clone.caseSensitiveAmbient = this.caseSensitiveAmbient;
clone.culture = this.culture;
clone.displayExpression = this.displayExpression;
clone.compareInfo = this.compareInfo;
clone.compareFlags = this.compareFlags;
clone.typeName = this.typeName;
clone.repeatableElement = this.repeatableElement;
clone.MinimumCapacity = this.MinimumCapacity;
DataColumnCollection columns = this.Columns;
for (int i = 0; i < columns.Count; i++)
{
clone.Columns.Add(columns[i].Clone());
}
if (cloneDS == null)
{
for (int m = 0; m < columns.Count; m++)
{
clone.Columns[columns[m].ColumnName].Expression = columns[m].Expression;
}
}
if (this.PrimaryKey.Length > 0)
{
int length = this.PrimaryKey.Length;
DataColumn[] columnArray = new DataColumn[length];
for (int n = 0; n < length; n++)
{
columnArray[n] = clone.Columns[this.PrimaryKey[n].Ordinal];
}
clone.PrimaryKey = columnArray;
}
for (int j = 0; j < this.Constraints.Count; j++)
{
if (!(this.Constraints[j] is ForeignKeyConstraint))
{
UniqueConstraint constraint = ((UniqueConstraint) this.Constraints[j]).Clone(clone);
Constraint constraint2 = clone.Constraints.FindConstraint(constraint);
if (constraint2 != null)
{
constraint2.ConstraintName = this.Constraints[j].ConstraintName;
}
}
}
for (int k = 0; k < this.Constraints.Count; k++)
{
if (!(this.Constraints[k] is ForeignKeyConstraint) && !clone.Constraints.Contains(this.Constraints[k].ConstraintName, true))
{
clone.Constraints.Add(((UniqueConstraint) this.Constraints[k]).Clone(clone));
}
}
if (this.extendedProperties != null)
{
foreach (object obj2 in this.extendedProperties.Keys)
{
clone.ExtendedProperties[obj2] = this.extendedProperties[obj2];
}
}
return clone;
}