从方法返回对象时,是创建了新实例还是引用?

时间:2011-08-12 19:19:35

标签: c# .net performance

  

可能重复:
  Do methods which return Reference Types return references or cloned copy?

我的一位同事说当一个方法返回一个像下面这样的对象时,会创建一个新的实例/副本,而不是传回一个引用:

public CustomerEntity Customer { get; set; }

public CustomerEntity GetCustomer() {
    Customer = new CustomerEntity();
    return Customer;    
}

这是对的吗?我的测试似乎表明不是这样,但我不确定如何确认这一点。他担心将数据复制到新对象的开销。

为了更好地衡量,以下哪种方法/方案是新对象创建的?调用类在哪些情况下访问原始对象的引用或副本?假设'CustomerEntity'是一个非常大的对象。

public class CustMan {
public CustomerEntity GetCustomer() {
    Customer = new CustomerEntity();
    return Customer
}

public void FillCustomer(CustomerEntity customer)
{
    customer = new CustomerEntity();
    // Calling class: 
    // CustomerEntity ce = new CustomerEntity(); 
    // l_custMan.FillCustomer(ce);  WriteLine(ce.Name);   
}

public void LoadCustomer()
{
    Customer = new CustomerEntity();
    // Calling Class access customerEntity via l_custMan.CustomerEntity
}
}

澄清:我的同事认为使用“加载”方法比使用“获取”方法更好:

l_custMan.Load();
CustomerEntity = l_custMan.Customer;

VS。

CustomerEntity = l_custMan.GetCustomer();

3 个答案:

答案 0 :(得分:8)

  

我的一位同事说当一个方法返回一个像下面这样的对象时,会创建一个新的实例/副本,而不是传回一个引用:

您的同事不正确 * 。对于作为引用类型的返回类型,始终会创建一个副本,只是它是所引用的引用的副本。

我可以更明确一点:

假设ReturnType是引用类型并且给定

public ReturnType M() {
    // some code
    return E;
}

其中E是一个表达式,其求值为I的{​​{1}}个实例,您询问是否制作了ReturnType的{​​{1}}副本并且对C的引用将返回给调用者,或者如果对I的引用返回给调用者。答案是对C的引用返回给调用者。

对于传递给方法的引用类型的参数(除非它们标有II),这是相同的:始终创建副本,它只是引用的副本过去了。

* :在他的辩护中,他可能会对C ++的一些知识感到困惑,你必须明确表示你要返回一个参考文献。

答案 1 :(得分:0)

虽然只返回了一个引用,但你的方法看起来很奇怪:

public CustomerEntity GetCustomer() {
    Customer = new CustomerEntity();
    return Customer;    
}

该名称表明它返回一个字段,而不是创建一个新对象,覆盖一个属性然后返回一个引用,所以这里每次都会创建一个 对象。

方法应该是这样的:

public CustomerEntity GetCustomer() {
    return Customer;    
}

但这是多余的,因为你的财产已有吸气剂。

我假设CustomerEntity是一个类而不是一个结构,对于结构创建一个副本

答案 2 :(得分:-1)

您将返回对该对象的引用。要创建“新”副本,您需要创建一个全新的实体。

public CustomerEntity GetCustomer() {
    CustomerEntity toReturn = new CustomerEntity();
    return toReturn ;    
}