首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >多个对象引用

多个对象引用
EN

Stack Overflow用户
提问于 2016-04-14 05:00:00
回答 3查看 1.6K关注 0票数 0

这个问题是关于对象引用的。

下面是我的帮助班。

代码语言:javascript
复制
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;
    }
}

现在,我在我的方法中使用上面的帮助类,如下所示

代码语言:javascript
复制
public string buildworkbook(Workbook workbook)
{
    helperv2 hlp=new helperv2();
    hlp.fillcolumnames(db,workbook);
    workbook=hlp.filldata(string sql);
}

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

  1. Buildworkbook获得一个空的工作簿实例。
  2. 现在填充列名,将所有列填充到工作簿,最后它指向主工作簿实例。
  3. 现在,填充数据在主工作簿实例上工作,并填充数据,然后它返回一个工作簿。

如您所见,我再次将其分配给工作簿实例并返回它。

这是可行的,但我无法理解这些多引用是如何工作的?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-04-14 06:22:32

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

所以如果你这么做

代码语言:javascript
复制
Workbook book;

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

代码语言:javascript
复制
Workbook book;
book.Title = "Hello"; //will throw NullReferenceException.

通过调用new创建新对象

代码语言:javascript
复制
//this code will create four new workbooks.
new Workbook();
new Workbook();
new Workbook();
new Workbook();

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

所以当你这么做的时候

代码语言:javascript
复制
var book = new Workbook();
var book2 = book;

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

返回值也是如此:

代码语言:javascript
复制
public Workbook DoSomething(Workbook book)
{
   book.Title = "Hello";
   return book;
}

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

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

由于变量是引用,所以不必使用返回值。要更改原始对象,这就足够了:

代码语言:javascript
复制
public void DoSomething(Workbook book)
{
   book.Title = "Hello";
}

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

现在回到你的密码。你设计你的util类的方式,没有人会明白它是如何工作的。主要教材什么时候还?工作簿何时作为参数传递?要么使所有方法都以工作簿作为参数,要么将工作簿作为构造函数参数传递。如果希望拥有主工作簿,请创建可用于分配该工作簿的方法或属性。有点像helper.AssignMainWoorkbook(workbook);

我的建议是,您根本不使用返回值,因为通过的工作簿将是方法修改的工作簿。

票数 4
EN

Stack Overflow用户

发布于 2016-04-14 05:28:10

我假设WorkBook是一个类。

  • 在类的情况下,每次声明类的变量(如Workbook myworkbook; )时,都会声明变量myworkbookWorkbook类型的,并且如果没有分配内存,它将存储一个空引用。
  • Workbook myworkbook = new Workbook(); --根据工作簿的类声明中声明的类成员,初始化对象并分配内存。同步块索引和类型对象指针的额外内存也与堆中的类成员一起分配。
  • 如果您尝试下面这样的声明,那么变量myworkbook2将只包含对已经创建的myworkbook的引用。因此,不使用额外的内存。但是,变量myworkbook2将位于内存堆栈中。 工作簿myworkbook =新工作簿();工作簿myworkbook2 = myworkbook;
  • 跨方法传递参数可以通过两种方式完成。经过referencevalue。在.net中,默认情况下参数通过值传递给方法。但是,如果要传递类,因为类是引用类型,则传递引用。因此,如果您对参数的属性进行了任何更改,则在调用函数中会反映相同的更改,在您的情况下正在发生这种情况。

来自MSDN的附加阅读:这里

引用类型的变量不直接包含其数据;它包含对其数据的引用。当您按值传递引用类型参数时,可以更改引用指向的数据,例如类成员的值。但是,您不能更改引用本身的值;也就是说,不能使用相同的引用为一个新类分配内存,并让它在块之外持久存在。为此,使用ref或out关键字传递参数。为了简单起见,下面的示例使用ref。

票数 1
EN

Stack Overflow用户

发布于 2016-04-14 06:32:59

在helper类中保持引用的位是您已经设置的一个小字段。是Workbook mainworkbook;

FillColumnnames()方法的末尾,通过传递给该方法的工作簿为该变量赋值,并且该变量现在总是在helperv2 hlp=new helperv2();对象中设置,因为您从未创建hlp的新对象,因此对mainworkbook的引用仍将分配给您在方法FillColumnnames()中传递的工作簿。

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

代码语言:javascript
复制
public WorkBook getWorkbook(){
    return this.mainworkbook;
}

然后在您的buildworkbook类中,您可以调用hlp.getWorkbook();来查看对象。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36614198

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档