这个问题是关于对象引用..
以下是我的助手班..
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);
}
现在我的问题是如何在下面的流程中跟踪这些多个对象引用。
如您所见,我再次将其分配给工作簿实例并将其返回
这有效,但我无法理解这些多个引用是如何工作的?
答案 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);
book2
和book
仍将指向同一个对象,因为所有类变量都包含对实际对象的引用。
由于变量是引用,因此您不必使用返回值。要改变原始对象就足够了:
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的Class声明中声明的类成员分配内存。同步块索引和类型对象指针的附加内存也与堆中的类成员一起分配。如果您尝试下面的声明,那么变量myworkbook2
将只包含对已创建的myworkbook
的引用。因此,不使用额外的存储器。但是,变量myworkbook2将存在于堆栈中。
Workbook myworkbook = new Workbook();
Workbook myworkbook2 = myworkbook;
跨方法传递参数可以通过两种方式完成。通过reference
或value
传递。在.net中,默认情况下,参数按值传递给方法。但是,如果要传递类,则由于该类是引用类型,因此将传递引用。因此,如果对参数的属性进行任何更改,则在调用函数中会反映相同的更改,这在您的情况下会发生。
引用类型的变量不直接包含其数据;它 包含对其数据的引用。传递引用类型时 参数值,可以更改指向的数据 引用,例如类成员的值。但是,你 不能改变引用本身的值;也就是说,你做不到 使用相同的引用为新类分配内存并拥有它 在街区外坚持。为此,请使用以下命令传递参数 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
查看该对象。