【问题标题】:How object reference variable works?对象引用变量如何工作?
【发布时间】:2015-07-24 22:31:34
【问题描述】:

在研究 .NET 反射 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  

【问题讨论】:

  • 这是什么语言?爪哇? C#?这不是 C。
  • "为什么没有创建对象的时候还有对象引用变量",currentAssem其实是Assembly类的一个实例所以这个对象已经被创建了
  • 如果存在从 int 到 Program 的隐式转换运算符,则可以执行“Program P = 2”
  • "new Program()" 只创建一个Program的新实例,它是"P = new Program()",将创建的对象存储在一个变量中
  • 我学习c#。非常感谢您的帮助!

标签: c# .net


【解决方案1】:

让我们首先考虑您的最后一个代码 sn-p:

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 实例。

最后,回到你的精细代码 sn-p:

Assembly currentAssem = Assembly.GetExecutingAssembly();

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

【讨论】:

    【解决方案2】:

    使用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.
    

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

    你不能这样做(当然,除非存在 cmets 中提到的隐式转换):

    Program P = 2;

    因为 2 不是 Program 类型并且不扩展 Program

    例如,假设您的 Program 类有一个方法 getNameofProgram()

    你可以P.getNameofProgram()吗?

    当然不是,2.getNameofProgram() 没有意义。

    至于你最后的代码sn-p,你有点误会了:

    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
    

    【讨论】:

      【解决方案3】:

      C#(或任何高级语言)并不是真正了解堆栈、堆和指针的最佳示例……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"
      

      当然还有更多关于拳击、范围、闭包等的细微差别 - 但这是基础。

      【讨论】:

        猜你喜欢
        • 2012-02-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-25
        • 2013-10-11
        • 2012-02-28
        • 2013-08-17
        • 1970-01-01
        相关资源
        最近更新 更多