Тип значения C # инициализируется нулем - PullRequest
7 голосов
/ 24 ноября 2010

В C # 3.0 вы можете присвоить null для int?тип (в CLR int? является структурой):

int? a = null;

, но когда вы определяете пользовательскую структуру:

struct MyStruct
{

}

во время компиляции этого кода возникает ошибка:

MyStruct a = null;

Ошибка выглядит следующим образом:

Cannot convert null to 'Example.MyStruct' because it is a non-nullable value type

Пока int?это структура в CLR, это как-то нелогично, что мы можем присвоить ему значение null.Я полагаю, что null неявно приводится или помещается в certian int?значение, которое представляет собой нулевое значение.Как это сделано точно?Как я могу расширить MyStruct таким образом, чтобы можно было выполнить строку:

MyStruct a = null;

Ответы [ 3 ]

20 голосов
/ 24 ноября 2010

Это потому, что int? на самом деле является сокращением Nullable<int>. Вы можете сделать то же самое для своего типа:

MyStruct? a = null;

null может быть неявно преобразовано только в тип , допускающий значение nullable , что означает любой ссылочный тип или любой тип значения, допускающий значение nullable, - где последний означает Nullable<T> для некоторого T.

Обратите внимание, что эта возможность конвертации из null действительно язык функция - компилятор конвертирует это:

int? a = null;

в

int? a = new int?();

Они означают одно и то же - в основном «нулевое» значение для типа значения, допускающего значение NULL, - это значение, где HasValue равно false, что будет по умолчанию. Это не то же самое, что нулевая ссылка - хотя добавление в ноль такого значения приведет к нулевой ссылке.

(Это один из примеров возможности, которая пересекает границы языка, библиотеки и CLR. Библиотечная часть довольно проста, часть CLR связана только с упаковкой и распаковкой - но есть довольно много с точки зрения поднятых операторов и т. Д. на языке.)

2 голосов
/ 24 ноября 2010

Структуры являются типами значений в C #, а не ссылочными типами, поэтому они не могут быть нулевыми.

MyStruct? = null;

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

public struct Point 
{
   public int x, y;

   public Point(int p1, int p2) 
   {
       x = p1;
       y = p2;    
   }
}

void Main()
{

    //create a point
    var point1 = new Point(10, 10); 

    //assign point2 to point, point2
    var point2 = point1; 

    //change the value of point2.x
    point2.x = 20; 

    //you will notice that point1.x does not change
    //this is because point2 is set by value, not reference.
    Console.WriteLine(point1.x);
    Console.WriteLine(point2.x);

}
1 голос
/ 24 ноября 2010

просто добавив, обнуляемый тип может представлять нормальный диапазон значений для его базового типа значения, плюс дополнительное нулевое значение.

В нотации, так же как int на самом деле является Int32, а не любым int,?Знак означает обнуляемый.Обнуляемый, в данном случае.

http://msdn.microsoft.com/en-us/library/1t3y8s4s%28VS.80%29.aspx

...