是否SqlCommand.Clone()
创建深层复制或浅层副本?另外,从多个线程同时调用Clone()
是否安全(创建一个多线程可以复制,设置参数值并执行的命令)?SqlCommand.Clone()是否创建深层副本或浅层副本?
回答
从多线程调用Clone
是不安全的,因为SqlCommand
类本身不是线程安全类。你应该lock
克隆前..
但是你可以看看使用像Reflector
程序SqlCommand.Clone()
方法,下面是实际的代码:
public SqlCommand Clone()
{
SqlCommand command = new SqlCommand(this);
Bid.Trace("<sc.SqlCommand.Clone|API> %d#, clone=%d#\n", this.ObjectID, command.ObjectID);
return command;
}
internal static void Trace(string fmtPrintfW, int a1, int a2)
{
if (((modFlags & ApiGroup.Trace) != ApiGroup.Off) && (modID != NoData))
{
NativeMethods.Trace(modID, UIntPtr.Zero, UIntPtr.Zero, fmtPrintfW, a1, a2);
}
}
[DllImport("System.Data.dll", EntryPoint="DllBidTraceCW", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Unicode)]
internal static extern void Trace(IntPtr hID, UIntPtr src, UIntPtr info, string fmtPrintfW, int a1, int a2);
private SqlCommand(SqlCommand from) : this()
{
this.CommandText = from.CommandText;
this.CommandTimeout = from.CommandTimeout;
this.CommandType = from.CommandType;
this.Connection = from.Connection;
this.DesignTimeVisible = from.DesignTimeVisible;
this.Transaction = from.Transaction;
this.UpdatedRowSource = from.UpdatedRowSource;
SqlParameterCollection parameters = this.Parameters;
foreach (object obj2 in from.Parameters)
{
parameters.Add((obj2 is ICloneable) ? (obj2 as ICloneable).Clone() : obj2);
}
}
你可以看到,它创建一个新的实例,并添加到它旧版本的所有属性,但它并不深拷贝所有属性“例如Connection
”,因此它是浅拷贝。
我不指望它克隆SqlConnection等critcal资源。我会说,因为它克隆了ICloneable的所有参数,它正在执行深度复制的“最佳尝试”。在应用程序中,我正在审查它从不使用'原始'SqlCommand,因此Connection和Transaction属性在'from'或'original'实例上始终为null。 – yzorg
@yzorg:对,但是因为它不能深入地克隆所有数据,比如'SqlConnection','Parameters' ..“,它被认为是一个浅拷贝。如果它深度复制所有数据,它只考虑“深层复制”,因此如果从原始或副本中更改任何属性,则不会影响另一个属性。 –
SqlCommand.Clone
方法执行浅拷贝。任何属于引用类型的属性都将在两个SqlCommand实例中表示相同的对象。所以,不是线程安全的。 AFAIK,.NET框架中的所有Clone()(MemberwiseClone)方法都是浅拷贝。
您还没有发布您的代码,但我建议您创建一个新的SqlCommand
而不是克隆。
- 1. QVector :: replace()是否创建深层副本?
- 2. Objective-C属性的复制属性创建了一个深层副本还是一个浅层副本?
- 3. OpenCV cv深层副本::垫
- 4. QML ListModel的深层副本
- 5. NSMutableDictionary的深层副本
- 6. 片段的深层副本
- 7. 是否存在无法创建深层副本的对象?
- 8. Javascrtip绑定,它是否创建`this`的深层副本?
- 9. tf.identity()是否创建完整的深层副本?
- 10. 在swift中创建集合类(Array,Dictionary)的浅表副本,而不是深层副本。
- 11. Groovy中的“each”和“eachWithIndex”是否会生成深度副本或浅度副本?
- 12. 切片操作是否提供深度或浅度副本?
- 13. 是否Arrays.copyOf产生浅或深的副本?
- 14. OrderedDict儿童的深层副本
- 15. C指针结构的深层副本
- 16. 派生python对象的深层副本
- 17. 使用深层副本实现递归
- 18. 熊猫面板的深层副本?
- 19. 制作字典的深层副本
- 20. 链接列表C++的深层副本
- 21. `shared_ptr`与`OMP平行深层副本firstprivate`
- 22. 可变的NSMutableDictionary深层副本
- 23. 一个NSMutableDictionary的深层可变副本
- 24. Ruby中数组的深层副本
- 25. 如何执行char *的深层副本?
- 26. 教条记录的深层副本
- 27. 二叉树的深层副本
- 28. kxml节点的深层副本(java me)
- 29. 对象图的JavaScript深层副本
- 30. PHP数组引用的深层副本
有关克隆,深浅拷贝和示例的更多信息,请参见[Object.MemberwiseClone](http://msdn.microsoft.com/zh-cn/library/system.object.memberwiseclone.aspx)方法http://stackoverflow.com/questions/699210/why-should-i-implement-icloneable-in-c/4186747#4186747 – Sreekumar
我的问题的原因是,如果它是从多线程的Clone()SqlCommand线程安全同时。从讨论看来,这似乎是真的,所以即使它不是一个深层克隆,它也会克隆参数集。因此,在启动时,您可以准备一次SqlCommand,然后从多个线程并行克隆它以节省一些工作。 – yzorg