C#. Значення null. Типи даних, допускаючих значення null

Значення null. Типи даних, допускаючих значення null. Операції ?, ??


Зміст


1. Значення null. Присвоєння

Значення null використовується для представлення пустого посилання на об’єкт. Це значення може бути присвоєне змінним посилальних типів.

Приклад.

У прикладі продемонстровано присвоювання null-значення посиланням на об’єкти класів CMyClass та string. Якщо спробувати присвоїти значення null змінній типу int, то компілятор видасть повідомлення про помилку.

class CMyClass
{
  public int value;
}

class Program
{
  static void Main(string[] args)
  {
    CMyClass obj;
    obj = null; // пусте посилання на об'єкт класу CMyClass
    string s = null; // пусте посилання на рядок

    // int d = null; - помилка: тип int не є null-типом
    Console.ReadKey();
  }
}

 

2. Синтаксис типу даних, який допускає значення null. Суфікс ?

У мові програмування C# усі базові числові типи даних (int, float, double, bool та інші) є типами-значеннями. Цим типам ніколи не може бути присвоєне значення null. Значення null може присвоюватись змінним посилальних типів, якими є класи.

Існують випадки, коли потрібно щоб тип-значення допускав null. Наприклад, в таблицях баз даних при деяких умовах можуть бути поля, що містять невизначені null-значення.

Для того, щоб тип-значення міг підтримувати null, в C# використовується наступна загальна форма, що містить символ ?

type? variable;

де

  • type – тип-значення, який повинен допускати значення null;
  • variable – назва змінної, якій може бути присвоєне значення null.

 

3. Приклади використання значень null у змінних базових типів

 

...

// Nullable-типи

// Це є помилка
// int d = null; // помилка - d не є Nullable-тип

// Так працює
int? d2 = null;

double? x;
x = 25;
x = null;

bool? b;
b = true;
b = null;

float? f;
f = null;

...


 

4. Суфікс ? і структура System.Nullable<T>. Призначення. Приклад

Якщо компілятор після імені типу зустрічає суфікс ?, то він створює екземпляр узагальненої структури System.Nullable<T>.

Структура System.Nullable<T> забезпечує додатковий набір засобів, що працюють з типами які допускають значення null. До цих засобів можна віднести:

  • властивість HasValue. Ця властивість визначає, чи поточний об’єкт типу System.Nullable<T> має стійке значення типу T (тут замість типу T задається будь-який базовий тип int, double і т.д.). Властивість повертає true, якщо поточний об’єкт має таке значення, в противному випадку повертається false (див. приклад нижче). Іншими словами, властивість HasValue повертає false, якщо значення об’єкту рівне null;
  • властивість Value – повертає поточне значення, яке присвоєне змінній типу, що допускає null;
  • метод GetValueOrDefault(). Якщо Nullable-змінна має значення не рівне null, то цей метод повертає це значення. Якщо Nullable-змінна рівна null, то метод повертає значення за замовчуванням (як правило це 0). Цей метод потрібно використовувати для коректного присвоювання значення з Nullable-типу у звичайний базовий тип.

Приклад.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp8
{
  class Program
  {
    static void Main(string[] args)
    {
      // 1. Оголошення змінної типу System.Nullable<int>
      System.Nullable<int> d; // можна було й так: int? d;

      // 2. Оголошення змінної типу System.Nullable<double>
      double? t = null;

      // 3. Властивість Value - демонстрація правильного присвоєння
      // тип int?
      d = null;
      int d2; // не Nullable-тип

      if (d == null)
        d2 = 0;
      else
        d2 = d.Value; // d2 = 335

      // тип double?
      t = -10.55;
      double t2;
      if (t != null)
        t2 = t.Value; // t2 = -10.55
      else
        t2 = 0.0;

      // 4. Властивість HasValue
      // Перевірка, чи змінна t рівна null
      t = null;
      if (t.HasValue)
        Console.WriteLine("t != null");
      else
        Console.WriteLine("t == null");

      // 5. Метод GetValueOrDefault() - не потрібно робити перевірку на null
      t = null;
      double t3 = t.GetValueOrDefault(); // t3 = 0 - значення за замовчуванням

      Console.WriteLine("d2 = {0}", d2);
      Console.WriteLine("t2 = {0}", t2);
      Console.WriteLine("t3 = {0}", t3);
      Console.ReadKey();
    }
  }
}

Результат виконання програми

t == null
d2 = 0
t2 = -10.55
t3 = 0

 

5. Як програмно визначити, чи Nullable-змінній було присвоєне значення null?

Якщо змінна допускає null, то визначити, чи містить ця змінна значення null можна наступними способами:

  • використати одну з операцій == або !=;
  • використати властивість HasValue.

Приклад.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp8
{
  class Program
  {
    static void Main(string[] args)
    {
      // Перевірка, чи Nullable-змінній було присвоєне значення null
      char? symbol; // деяка Nullable-змінна

      // Спосіб 1. Операція ==
      symbol = null;
      if (symbol == null)
        Console.WriteLine("symbol == null");
      else
        Console.WriteLine("symbol != null");

      // Спосіб 2. Операція !=
      symbol = 'a';
      if (symbol != null)
        Console.WriteLine("symbol != null");
      else
        Console.WriteLine("symbol == null");

      // Спосіб 3. Властивість HasValue
      symbol = null;
      if (symbol.HasValue)
        Console.WriteLine("symbol != null");
      else
        Console.WriteLine("symbol == null");
      Console.ReadKey();
    }
  }
}

Результат роботи програми

symbol == null
symbol != null
symbol == null

 

6. Операція ??. Призначення. Приклад

Операція ?? дозволяє присвоювати об’єкту Nullable-типу задане значення у випадку, коли значення цього об’єкту рівне null. Операція дозволяє замінити програмний код, що використовує конструкцію if-else. Порівняно з if-else ця операція є більш компактною.

Приклад.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp8
{
  class Program
  {
    static void Main(string[] args)
    {
      // Операція ??
      uint? d; // деякий Nullable-тип
      uint? t;

      d = null;
      t = d ?? 50; // t = 50
      Console.WriteLine("t = {0}", t);

      d = 20;
      t = d ?? 50; // t = 20
      Console.WriteLine("t = {0}", t);

      Console.ReadKey();
    }
  }
}

Результат роботи програми

t = 50
t = 20

 


Зв’язані теми