1

情况如下:我试图确定克隆对象的位置部分以避免修改原始对象。

我有两个选择:

  • 调用者中克隆对象并将克隆的对象传递给方法(“被调用者”),从而防止被调用者进行潜在的修改。
  • 克隆被调用者中的对象,因为被调用者修改了它传递的对象,这假设调用者从不希望修改参数对象。

我找到了这个 6 岁的答案,有各种各样的意见。不幸的是,似乎没有真正的共识。

将对象的副本传递给方法——谁来复制?

这是我的代码形式的问题:

  • 我是否在调用者中克隆对象并将克隆的对象传递给方法?
public static void Main()
{
    var foo = new Foo();
    Bar.Baz(foo.DeepClone());
}

public static class Bar
{
    public static void Baz(Foo foo)
    {
        /* ... modifies members in foo ... */
    }
}

public class Foo { /* ... */ }
  • 我是否克隆被调用者中的对象?
public static void Main()
{
    var foo = new Foo();
    Bar.Baz(foo);
}

public static class Bar
{
    public static void Baz(Foo foo)
    {
        foo = foo.DeepClone();
        /* ... modifies members in foo ... */
    }
}

public class Foo { /* ... */ }

所以,我的问题是:

  • 对于跨语言克隆对象的位置有哪些好的经验法则,尤其是在 C# 和 .NET 领域?

  • 不管答案如何,有哪些好的方法可以记录修改参数的方法或克隆对象的方法的行为?

4

2 回答 2

2

该方法的目的是改变对象吗?然后不要在方法内部克隆。你希望副作用发生。通常,方法名称会清楚地指出预期会发生突变的事实(例如UpdateCustomer)。

If it is not the explicit purpose of the method to mutate its inputs then the mutation is an implementation detail and the method must see to it that the mutation does not leak out. It can do that by cloning.

Methods should not use their inputs as mere scratch space. Some in the Win32 APIs do that which is horribly confusing.

于 2015-06-17T22:52:57.323 回答
1

The best way to enforce (and document) constness is to define a read only interface and define your parameter as that interface. Anything that accepts the interface is constant and anything that accepts the full object might mutate the object.

If you are following this approach, the caller should be cloning if it does not want the side effects since we have given permission to the callee to modify the object by passing it a modifiable object.

于 2015-06-17T23:12:23.827 回答