对象引用变量如何工作?

时间:2015-07-24 13:56:39

标签: c# .net

在我研究.NET Reflection API时,我遇到了以下代码。

Assembly currentAssem = Assembly.GetExecutingAssembly();

我理解下面的代码。

Assembly = Class Name   
currentAssem = object reference variable  
Assembly.GetExecutingAssembly = Static method in Assembly class

但是,我认为对象引用变量(在堆栈中)只保存对实际对象的引用(在堆中)。当没有创建对象时,为什么有一个对象引用变量,我有点困惑。对象引用变量是否保存方法中返回的数据?或其他什么?

为类或结构创建变量时,它是否始终是对象引用变量?我的意思是您可以执行以下操作,将2分配给a

int a = 2;

你能为一堂课做吗?例如,如果我的班级名称为Program并且我创建了一个变量P - 我可以执行以下操作吗?

Program P = 2;

我是否正确理解以下代码?

Program P = new Program();

P =  object reference variable   
new Program = It makes P point to an object of type Program  

3 个答案:

答案 0 :(得分:2)

让我们先考虑你的最后一段代码:

Program p = new Program();

p这是一个Program引用变量。 object引用变量将定义为:

object o = new Program();

Program(和所有内容)继承自object时,您可以将Program的实例分配给o

现在考虑这一部分:

new Program()

这将创建Program类的新实例。在代码行Program p = new Program();中,该引用随后会分配给p

现在考虑以下事项:

Program p1 = new Program();
Program p2 = p1;

在这里,我们正在创建一个新的Program对象,并将其引用分配给p1。然后,下一行将该引用复制到p2。因此,现在p1p2都引用相同的Program实例。

最后,回到你的精细代码片段:

Assembly currentAssem = Assembly.GetExecutingAssembly();

这就像我们的Program p2 = p1;行。 Assembly.GetExecutingAssembly();是一个静态方法,它返回对Assembly实例的引用(在本例中是运行代码的程序集)。 Assembly currentAssem =然后将该引用复制到currentAssem

答案 1 :(得分:0)

使用this链接告诉我们Assembly.getExecutingAssembly()返回类型System.Reflection.Assembly。 (无论如何,都在C#。)

因此,对它的引用是Assembly类型是有意义的,因为该方法返回该类型的引用。

David Arno就其运作方式做了一个很好的例子:

Program P1 = new Program();
Program P2;
P2 = P1 // This step is exactly how the line containing the Assembly.getExecutingAssembly() method works.

是的,您仍然可以将对象引用变量指向对象。您可以稍后将其指定为引用堆上的某个对象。

您不能这样做(当然,除非评论中提到了隐式转换):

Program P = 2;

因为2不是Program类型,并且不会延伸Program

例如,我们假设您的Program课程有getNameofProgram()方法。

你可以P.getNameofProgram()吗?

当然不是,做2.getNameofProgram()毫无意义。

至于你的上一段代码片段,你有点误会:

Program P = new Program();

Program P // Makes an Object reference Variable of type Program;
new Program() // Makes a new Instance of Program
= // Tells P to reference that Instance of the Program we just made

答案 2 :(得分:0)

C#(或任何高级语言)并不是了解堆栈与堆和指针的最佳示例......在IMO幕后工作中,IMO很复杂。

那就是说,我认为你基本上是正确的但却错过了你可以复制"对象引用变量*的事实。由于它们是引用类型,因此两个副本指向堆上的同一对象。

因此,在第一个示例中,静态方法Assembly.GetExecutingAssembly返回一个对象引用变量,然后将其复制到currentAssem变量中。现在(至少)有两个变量指向堆上的相同位置。

  

为类或结构创建变量时,它是否始终是对象引用变量?

不,结构是值类型。为它们创建变量时,变量包含数据 - 它们不指向堆。值类型的行为与引用类型不同;复制它们时,会复制内容并获得一个全新的变量。

在你的第二个例子中:

Program P = new Program();

它基本上是这样的:

P: create a location on the stack to store a memory address
new Program(): create a new Program instance on the heap
   return the address where it was created
=: copy the returned address into the location called "P"

当然,拳击,范围,封闭等方面的细微差别 - 但这是基础。