是否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