在 C# 中,_where_ 克隆对象有哪些经验法则?

In C#, what are some rules of thumb for _where_ to clone objects?

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

我有两个选择:

我发现这个 6 岁的答案有多种观点。不幸的是,似乎并没有达成真正的共识。

Passing copy of object to method -- who does the copying?

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

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 { /* ... */ }

所以,我的问题是:

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

如果方法的明确目的不是改变其输入,那么突变是一个实现细节,并且该方法必须确保突变不会泄露出去。它可以通过克隆来做到这一点。

方法不应仅将其输入用作草稿 space。 Win32 API 中的某些 API 会做一些非常令人困惑的事情。

实施(和记录)常量的最佳方法是定义一个只读接口并将您的参数定义为该接口。任何接受接口的东西都是常量,任何接受完整对象的东西都可能改变对象。

如果您遵循这种方法,如果调用者不希望出现副作用,则它应该进行克隆,因为我们已经允许被调用者通过传递一个可修改的对象来修改对象。