多个对象引用

时间:2016-04-14 05:00:01

标签: c# .net object

这个问题是关于对象引用..

以下是我的助手班..

class helperv2
{
    Workbook mainworkbook;
    //fill column names method
    public void FillColumnnames(DatabaseAdapter db,Workbook workbook)
    {
        //do some random stuff 

        //at the end of method
        mainworkbook = workbook;
    }
    public Workbook filldata(string sql)
    {
        //do some work on mainworkbook instance and return mainworkbook

        return mainworkbook;
    }
}

现在我在我的一个方法中使用上面的helper类,如下所示

public string buildworkbook(Workbook workbook)
{
    helperv2 hlp=new helperv2();
    hlp.fillcolumnames(db,workbook);
    workbook=hlp.filldata(string sql);
}

现在我的问题是如何在下面的流程中跟踪这些多个对象引用。

  1. Buildworkbook获取传递的空工作簿实例
  2. 现在填写列名称,将所有列填充到工作簿中 最后它指向mainworkbook实例。
  3. 现在填充数据在mainworkbook实例上工作并填充数据和 它返回一个工作簿..
  4. 如您所见,我再次将其分配给工作簿实例并将其返回

    这有效,但我无法理解这些多个引用是如何工作的?

3 个答案:

答案 0 :(得分:4)

.NET中对象的所有变量都是引用。这意味着类的所有变量都只是实际对象的链接。变量不包含它。

所以,如果你这样做:

Workbook book;

你没有得到一个实际的对象。您可以尝试修改它来自己尝试:

Workbook book;
book.Title = "Hello"; //will throw NullReferenceException.

您可以致电new

来创建新对象
//this code will create four new workbooks.
new Workbook();
new Workbook();
new Workbook();
new Workbook();

但由于您没有在变量中存储引用,因此垃圾收集器将删除这些对象,因为将收集所有未引用的对象。

所以当你这样做时:

var book = new Workbook();
var book2 = book;

您只需声明book2应指向与book相同的对象。没有创建新对象。

返回值也一样:

public Workbook DoSomething(Workbook book)
{
   book.Title = "Hello";
   return book;
}

var book = new Workbook();
var book2 = DoSomething(book);

book2book仍将指向同一个对象,因为所有类变量都包含对实际对象的引用。

由于变量是引用,因此您不必使用返回值。要改变原始对象就足够了:

public void DoSomething(Workbook book)
{
   book.Title = "Hello";
}

var book = new Workbook();
DoSomething(book);
// 'book' now got a new title.

现在回到你的代码。你设计你的util类的方式,没有人会理解它是如何工作的。什么时候会把主要的wookbook归还?何时返回作为参数传递的工作簿?要么使所有方法都将工作簿作为参数,要么将工作簿作为构造函数参数传递。如果要拥有主工作簿,请创建可用于分配它的方法或属性。类似于helper.AssignMainWoorkbook(workbook);

我的建议是你只是不使用返回值,因为传递的工作簿将是由方法修改的工作簿。

答案 1 :(得分:1)

我将假设WorkBook是一个类。

  • 在类的情况下,每次声明类Workbook myworkbook;之类的变量时,它都是一个声明,变量myworkbook的类型为Workbook,并且它将存储空引用为没有分配内存。
  • Workbook myworkbook = new Workbook();这会初始化对象并根据Workbook的Cla​​ss声明中声明的类成员分配内存。同步块索引和类型对象指针的附加内存也与堆中的类成员一起分配。
  • 如果您尝试下面的声明,那么变量myworkbook2将只包含对已创建的myworkbook的引用。因此,不使用额外的存储器。但是,变量myworkbook2将存在于堆栈中。

     Workbook myworkbook = new Workbook();
     Workbook myworkbook2 = myworkbook;
    
  • 跨方法传递参数可以通过两种方式完成。通过referencevalue传递。在.net中,默认情况下,参数按值传递给方法。但是,如果要传递类,则由于该类是引用类型,因此将传递引用。因此,如果对参数的属性进行任何更改,则在调用函数中会反映相同的更改,这在您的情况下会发生。

来自MSDN,附加阅读:here

  

引用类型的变量不直接包含其数据;它   包含对其数据的引用。传递引用类型时   参数值,可以更改指向的数据   引用,例如类成员的值。但是,你   不能改变引用本身的值;也就是说,你做不到   使用相同的引用为新类分配内存并拥有它   在街区外坚持。为此,请使用以下命令传递参数   ref或out关键字。为简单起见,以下示例使用ref。

答案 2 :(得分:1)

保持你的引用进入助手类的位是你设置的一个小字段。这是Workbook mainworkbook;

FillColumnnames()方法的末尾,您将该变量与传递给该方法的工作簿一起分配,并且现在始终在helperv2 hlp=new helperv2();的对象中设置,因为您从未创建{的新对象{1}},hlp内部的引用仍将分配给您在方法mainworkbook中传递的工作簿。

这意味着,在您调用FillColumnnames()函数后,它会返回fillData类中mainworkbook参数中存储的值。如果您想进一步检查它,可以在helperv2类中创建一个getter,并在流程的每一步检查它,如:

helperv2

然后在public WorkBook getWorkbook(){ return this.mainworkbook; } 课程中,您可以致电buildworkbook查看该对象。