Может ли структура действительно не быть нулевой в C #? - PullRequest
28 голосов
/ 21 мая 2011

Ниже приведен код, демонстрирующий, что я не могу объявить и инициализировать тип структуры как ноль. Тип Nullable является структурой, так почему я могу установить для него значение null?

Nullable<bool> b = null;
if (b.HasValue)
{
    Console.WriteLine("HasValue == true");
}

//Does not compile...
Foo f = null;
if (f.HasValue)
{
    Console.WriteLine("HasValue == true");
}

Где Foo определяется как

public struct Foo
{
    private bool _hasValue;
    private string _value;

    public Foo(string value)
    {
        _hasValue = true;
        _value = value;
    }

    public bool HasValue
    {
        get { return _hasValue; }
    }

    public string Value
    {
        get { return _value; }
    }
}

На вопрос дан ответ (см. Ниже). Чтобы уточнить я выложу пример. Код C #:

using System;

class Program
{
    static void Main(string[] args)
    {
        Nullable<bool> a;
        Nullable<bool> b = null;
    }
}

производит следующий IL:

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       10 (0xa)
  .maxstack  1
  .locals init ([0] valuetype [mscorlib]System.Nullable`1<bool> a,
           [1] valuetype [mscorlib]System.Nullable`1<bool> b)
  IL_0000:  nop
  IL_0001:  ldloca.s   b
  IL_0003:  initobj    valuetype [mscorlib]System.Nullable`1<bool>
  IL_0009:  ret
} // end of method Program::Main

a и b объявлены, но инициализируется только b.

Ответы [ 4 ]

24 голосов
/ 21 мая 2011

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

Nullable<bool> b = new Nullable<bool>();

Вот синтаксический сахар

bool? b = null;    
if (b ?? false) 
{
   b = true;
}
13 голосов
/ 21 мая 2011

C # имеет некоторый синтаксический сахар, который позволяет отображать для типа nullable тип null.То, что вы на самом деле делаете под прикрытием, устанавливает для свойства HasValue типа nullable значение false.

3 голосов
/ 21 мая 2011

Поскольку вы на самом деле не устанавливаете переменную Nullable<T> в null. Структура все еще там. Он представляет null через внутренний битовый флаг в структуре.

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

2 голосов
/ 21 мая 2011

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

...