2017-01-19 4 views
1

Когда мы объявляем только объект класса, не создавая его, как показано ниже, обрабатывает ли он значение null или пустое?Объявление объекта класса как null

Example1: Directory objDEntry;

Example2: Directory objDEntry = null;

Есть ли разница между example1 и example2 или они одинаковы?

+1

Оба они одинаковы, поскольку значение «null» является значением по умолчанию для всех ссылочных типов переменных. –

+0

Технически это будет иметь значение null. Однако компилятор C# не позволит вам использовать объект, пока ему не будет явно присвоено значение (даже если это значение равно «null»). – Abion47

+1

нет разница, обе - null. Но в некоторых типах значение defualt, например int X; X по умолчанию 0. – onur

ответ

2

От от; если вы объявите поле , например.

public class MyClass { 
    // objDEntr will be initialized by null 
    Directory objDEntr; 
    // the initialization is redundant here 
    Directory objDEntry2 = null; 
    ... 

нет никакой разницы, так как поля инициализируются их значения по умолчанию и null значения по умолчанию для ссылочных типов. Однако локальные переменные не инициализируются по умолчанию; так

public static void MyMethod() { 
    // objDEntry contains trash, must be initialized further 
    Directory objDEntry; 
    // objDEntry2 is null 
    Directory objDEntry2 = null; 
    ... 

в «Пример 1» objDEntry содержит мусор, в то время как в примере 2 «» objDEntry правильно инициализирован и содержит null.

0

Когда вы объявляете переменную ссылочного типа, переменная в основном является указателем на коллекцию памяти, которая представляет конкретный объект. Например, в вашем случае, когда вы объявляете переменную Dictionary:

Dictionary objDict; 

Это создает указатель, который будет указывать на Dictionary объекта в памяти. Однако, когда он впервые объявлен таким образом, переменная фактически не указывает ни на что. Попытка использовать переменную в любых вычислениях в этой точке приведет к NullReferenceException.

С другой стороны, при создании объекта он выделяет память для этого объекта. (. Ради этого объяснения, именно там, где она выделяет память не имеет значения) Так что, когда вы создаете объект Dictionary:

new Dictionary(); 

Это будет выделять память, необходимую для представления Dictionary объекта.

Когда вы связываете эти два действия вместе, то есть то, что вы делаете, когда вы назначаете переменную ссылки типа:

Dictionary objDict = new Dictionary(); 

Переменная objDict теперь указывает на память, выделенную для объекта.

Теперь, когда вы присваиваете ссылочную переменную null, вы в основном возвращаете ее в состояние по умолчанию - состояние, в котором указатель ничего не указывает. В этом смысле, строки:

Dictionary objDict; 

и

Dictionary objDict = null; 

будут идентичны, насколько CLR обеспокоен. Однако компилятор C# поставляется со своим набором ограничений, в котором рассматриваются объявления переменных.В результате ошибок компиляции будет задано указание, что ссылочная переменная не может использоваться до тех пор, пока не будет гарантировано, что она была бы явно создана. Например, следующий будет компилировать, но выдаст ошибку во время выполнения:

Dictionary objDict = null; 
string s = objDict.ToString(); 

Этот код, однако, потерпит неудачу при компиляции, с сообщением об ошибке в «Использование неназначенную локальной переменной" objDict» :

Dictionary objDict; 
string s = objDict.ToString(); 

Как считает Дмитрий в своем ответе, это правило применяется только к локальным переменным. Класса и выше переменных не будет производить такую ​​ошибку, поэтому следующий код будет хорошо:

Dictionary objDict; 

public void DictToString() 
{ 
    string s = objDict.ToString(); 
} 

Чтобы объяснить, что Хамид говорит о, ссылка переменная является указателем на объект в памяти , но когда вы берете назначенную переменную и устанавливаете ее на null, этот предыдущий объект все еще находится в памяти - он только что был осиротевшим. Когда CLR выполняет сбор мусора, он проверяет именно эти осиротевшие объекты и освобождает их память.

Он не будет (обычно) собирать объекты, которые все еще имеют активные указатели, указывающие на них, однако, поэтому для некоторых объектов это может быть хорошей практикой избавиться от них, установив для них переменные, указывающие на них null, они будут правильно выпущены в следующий раз, когда появится сбор мусора.