性能/风格:通过引用更改对象与在C#中返回副本

时间:2012-08-09 03:41:51

标签: c# .net performance garbage-collection styles

首先让我提供背景信息:

在C#中,传递给方法的对象通过引用传递。如果使用关键字new重新实例化传入的对象

,则仅丢失引用

所以,我喜欢做var obj = Alter(obj) (方法1)之类的事情,即我传入一个对象并返回该对象。与执行等效操作相反:Alter(obj) (方法2),其中引用的对象更改相同,除非通过引用而不是返回副本。我认为第一个更好,因为如果一些冒失鬼编码器后来修改代码使用关键字“新”...现有代码将不会燃烧和死亡。

我的问题是方法1 会比方法2 使用更多的内存,还是会导致其他任何性能下降?即,这会更频繁地调用GC吗?

  
    

答案是否

  

3 个答案:

答案 0 :(得分:4)

  

在C#中,传递给方法的对象通过引用传递。仅当使用关键字new

重新实例化传入的对象时,才会丢失引用

不,不,至少默认情况下不是。默认情况下,所有都按值传递。碰巧的是,在引用类型的情况下,通过值传递的东西是引用。

因此,引用的副本。这也反驳了第二个陈述。您可以随意重新分配方法参数;你只是修改一个副本。这也改变了你的问题的含义,因为你继续说...

  

所以,我喜欢做var obj = Alter(obj)(方法1)之类的事情...我认为第一个更好,因为如果一些冒失鬼程序员稍后修改代码使用关键字“new”。 ..现有代码不会燃烧而死。

不会发生这种情况。其次,如果你与那些签入代码的程序员一起工作并且他们没有测试,那么你就会遇到更大的问题。但是,“在参考副本上使用new关键字”无论如何都是无关紧要的(至少在影响原始版本方面)。即使你的方法是正确的,这也会过于防守。

我的问题是;如果你的函数只用于改变其单个输入的状态,那么为什么这个方法不是一个类型的实例方法呢?

答案 1 :(得分:3)

C#从不复制引用类型。如果您将 obj 传递给您的方法然后返回它,那就是您开始使用的完全相同的对象实例。

这不会给GC带来额外的压力。

答案 2 :(得分:1)

通常,不修改指定为方法输入的参数会更安全。至于性能,这两者之间的内存消耗差异几乎肯定可以忽略不计,绝对不会成为程序中的性能瓶颈。这是一个预成熟优化的案例。

除非您有证据表明性能差异导致程序出现问题,否则您应该选择更清洁,更安全的解决方案。