【问题标题】:When (deep) Cloning, use String.Copy or str1 = str2?(深度)克隆时,使用 String.Copy 还是 str1 = str2?
【发布时间】:2011-01-21 00:41:36
【问题描述】:

当(深度)克隆自定义对象时,我应该使用clone.str1 = String.Copy(obj.str1) 还是clone.str1 = obj.str1

我更喜欢后者——更短、更快,但它“安全”吗?

我会指向this thread,但是,不确定要使用什么。

【问题讨论】:

    标签: .net string clone


    【解决方案1】:

    调用String.Copy 将创建一个单独的字符串副本。
    由于字符串是不可变的,因此没有必要这样做。

    【讨论】:

    • 所以,明白了,我可以使用 a = b。但是,并不总是安全的,例如(来自提供的链接):“如果您将字符串与直接处理内存位置并可以改变字符串的非托管代码一起使用,这可能很重要。”
    • 您真的在处理会就地改变字符串的非托管代码吗?
    【解决方案2】:

    当进行深度克隆时,为什么不直接使用 BinaryFormatter 呢?

    this link

    这是我在那个链接上写的代码:

    public Automobile Clone()
    {
        Automobile result = null;
        using (MemoryStream ms = new MemoryStream())
        {
             BinaryFormatter bf = new BinaryFormatter();
             bf.Serialize(ms, this);
             ms.Position = 0;
             result = (Automobile)bf.Deserialize(ms);
         }
         return result;
    }
    

    【讨论】:

    • 二进制格式化程序的技巧很方便,尤其是对于现有的类。但是,它远不及 与编写自己的深度克隆一样快或内存效率高。它不应该是您的首选方法。
    • 循环引用问题。
    • 循环引用应该没问题。但是不可序列化的类将是一个问题。
    • @SealedSun:你为什么说“还好”?我不能对有父对象的对象进行二进制序列化。
    • 二进制序列化中的循环引用没有问题……而且速度很快……而且不需要维护……如果实施得当,它可以跨类重用。
    【解决方案3】:

    进行深度克隆时,您需要克隆每个可变值。字符串在 .NET 上是可变的,所以是的,你应该克隆它。

    edit: 哎呀......似乎它们是不可变的,所以不,你不需要。

    【讨论】:

    • @serhio:不,对不起,我错了。我假设 String 是可变的,因为它有一个 insert 方法,但实际上这会返回一个新字符串。这也是为什么 clone 返回字符串本身。
    • 我明白了。但是,字符串仅在托管代码中是不可变的;)
    • @serhio: 是的,好吧,如果来自低级语言黑暗地狱的邪恶灵魂出现并篡改您的数据,那么一切皆有可能,但没有什么是有效的......:D
    【解决方案4】:

    是的 - 后一种选择(简单赋值)对于字符串(在托管代码中)是安全的,如下代码所示:

        string s1 = "Initial Value";
        string s2 = s1;
    
        Console.WriteLine("String1: " + s1);
        Console.WriteLine("String2: " + s2);
    
        s1 = "New Value";
    
        Console.WriteLine("String1 - after change: " + s1);
        Console.WriteLine("String2 - after change: " + s2);
    

    输出:

    String1: Initial Value
    String2: Initial Value
    String1 - after change: New Value
    String2 - after change: Initial Value
    

    字符串是不可变的——所以当您更改 s1 时,您实际上是在创建一个新字符串并对其进行分配。 s2 的引用仍然指向旧实例。

    【讨论】:

    • 没有什么问题,但在后台它使用不安全的代码对字符串进行字符复制。我猜这意味着您正在执行不必要的复制操作。
    猜你喜欢
    • 2010-09-16
    • 1970-01-01
    • 1970-01-01
    • 2013-08-11
    • 1970-01-01
    • 1970-01-01
    • 2019-09-06
    • 2017-09-01
    相关资源
    最近更新 更多