2015-07-24 2 views
0

Пока я изучал API .NET Reflection, я натолкнулся на следующий код.Как работает эталонная переменная объекта?

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 
+1

На каком языке это? Ява? C#? Это не C. – dbush

+0

«почему существует ссылочная переменная объекта, когда объект не создан», currentAssem на самом деле является экземпляром класса Assembly, поэтому этот объект был создан. –

+1

Вы можете сделать «Program P = 2», если есть неявный оператор преобразования из int в программу –

ответ

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. Так что теперь и p1, и p2 относятся к тому же Program экземпляру.

Наконец, обратно в ваш прекрасный фрагмент кода:

Assembly currentAssem = Assembly.GetExecutingAssembly(); 

Это как наш Program p2 = p1; линии. Assembly.GetExecutingAssembly(); - это статический метод, возвращающий ссылку на экземпляр Assembly (в данном случае сборку, в которой работает ваш код). Затем Assembly currentAssem = копирует эту ссылку в currentAssem.

0

Использование this link это сообщает нам, что Assembly.getExecutingAssembly() возвращает тип System.Reflection.Assembly. (В C#, во всяком случае).

Так что имеет смысл, что ссылка на него имеет тип Assembly, так как метод возвращает ссылку этого типа.

Дэвид 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 
0

C# (или любой другой язык высокого уровня) на самом деле не лучший пример, чтобы узнать о стеке против кучи и указатели ... есть много за кулисами работает, что ИМО усложняет вопросы.

То есть, я думаю, что у вас есть это в принципе правильно, но не хватает на то, что вы можете скопировать «ссылка на объект переменных *. Так как они являются ссылочными типами, две копии указывают на тот же объект в куче.

Так, в первом примере, статический метод 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" 

Там же, конечно, больше нюансов вокруг бокса, обзорного, закрытий и т.д. - но это основы.