SqlCommand.Clone()是创建深拷贝还是浅拷贝?

时间:2011-07-26 04:32:16

标签: .net clone sqlcommand

SqlCommand.Clone()是否会创建深层副本或浅层副本?此外,同时从多个线程调用Clone()是否安全(创建一个多线程可以复制,设置参数值和执行的命令)?

2 个答案:

答案 0 :(得分:3)

从多个线程调用Clone是不安全的,因为SqlCommand类本身不是线程安全类。在克隆之前你应该lock ..

但是,您可以使用SqlCommand.Clone()等程序查看Reflector方法,以下是实际代码:

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”,因此它是一个浅层副本。

答案 1 :(得分:2)

SqlCommand.Clone方法执行浅拷贝。作为引用类型的任何属性都将表示两个SqlCommand实例中的同一对象。所以,不是线程安全的。

AFAIK,.NET框架中的所有Clone()(MemberwiseClone)方法都是浅层副本。

您尚未发布代码,但我建议您创建新的SqlCommand而不是克隆。