Ключем до розуміння того, що null!
означає, є розуміння !
оператора. Можливо, ви раніше використовували його як оператор "не". Але оскільки C # 8.0, оператор також може бути використаний на типі для контролю Nullabilty
Що таке !
оператор при використанні на типі?
!
Оператора, коли використовується на типі, називається Null прощає Оператор [ документи ]. Він був введений в C # 8.0
Технічне пояснення
Типове використання
Припускаючи це визначення:
class Person
{
public string? MiddleName;
}
Використання:
void LogPerson(Person person)
{
Console.WriteLine(person.MiddleName.Length);
Console.WriteLine(person.MiddleName!.Length);
}
Цей оператор в основному вимикає перевірку нуля компілятора.
Внутрішні відпрацювання
Використання цього оператора повідомляє компілятору, що щось, що може бути нульовим, є безпечним для доступу. Ви висловлюєте намір "не піклуватися" про нульову безпеку в цьому випадку.
Існує 2 стани, в яких може бути змінна - коли йдеться про нульову безпеку.
- Nullable - може бути нульовим.
- Non-Nullable - не може бути нульовим.
Оскільки C # 8.0, всі типи посилань за замовчуванням не мають нульового значення.
"Онульованість" може бути змінена цими 2 новими операторами типу:
!
= Від Nullable
доNon-Nullable
?
= Від Non-Nullable
доNullable
Ці оператори в основному є аналогами один одному. Компілятор використовує інформацію - яку ви визначаєте з цими операторами - для забезпечення нульової безпеки.
?
Використання оператора.
Допустимий string? x;
x
є посилальним типом - Отже, за замовчуванням не має нульового значення.
- Ми застосовуємо
?
оператор - що робить його нульовим.
x = null
Працює нормально.
Непущений string y;
y
є посилальним типом - Отже, за замовчуванням не має нульового значення.
y = null
Генерує попередження, оскільки ви присвоюєте нульове значення тому, що не повинно бути нульовим.
!
Використання оператора.
string x;
string? y = null;
x = y
- Незаконне! -
Warning: "y" may be null
- Ліва частина завдання не може бути відхилена, але права частина - відхилена.
x = y!
- Легально!
- Права та ліва сторони завдання не мають нульового значення.
- Працює з
y!
Застосовує !
оператор, для y
якого він не має нульового значення.
ПОПЕРЕДЖЕННЯ В !
операторі включається тільки від компілятора перевірок на рівні типу системи - Під час виконання, значення все ще може бути порожнім.
Це анти-шаблон.
Ви повинні намагатися , щоб уникнути використання !
Null прощає-оператора.
Існують дійсні випадки використання (докладно описані нижче), такі як модульні тести, де цей оператор доцільно використовувати. Однак у 99% випадків вам краще запропонувати альтернативне рішення. Будь ласка, не ляпайте десятки символів !
вашого коду, аби просто замовкнути попередження. Подумайте, чи дійсно ваша справа вимагає використання.
Використовуйте - але обережно. Якщо конкретної мети / випадку використання немає, волійте не використовувати її.
Це заперечує наслідки нульової безпеки, яку вам гарантує компілятор.
Використання !
оператора створить дуже важкі для пошуку помилки. Якщо у вас є властивість, яка позначена як ненульована, ви вважаєте, що можете використовувати її безпечно. Але під час роботи ти раптом стикаєшся з NullReferenceException
і чешеш голову. Оскільки значення фактично стало нульовим після обходу компілятор-перевірок за допомогою !
.
Чому тоді існує цей оператор?
- У деяких крайових випадках компілятор не може виявити, що значення, що допускає нуль, насправді не має значення.
- Простіше перенесення застарілої кодової бази.
- У деяких випадках вам просто байдуже, якщо щось стане нульовим.
- Під час роботи з модульними тестами вам може знадобитися перевірити поведінку коду, коли проходить a
null
.
Відповідаючи конкретно на ваше запитання.
То що null!
означає?
Він повідомляє компілятору, що null
це не null
значення. Звучить дивно, чи не так?
Це те саме, що y!
з прикладу вище. Це виглядає лише дивним, оскільки ви застосовуєте оператор до null
літералу . Але концепція однакова.
Розбираючи те, що відбувається.
public string LastName { get; } = null!;
Цей рядок визначає властивість класу, що не має дозволу, з іменем LastName
типу string
. Оскільки він не має нульового значення, ви технічно не можете призначити йому null - очевидно.
Але ви тільки що - Присвоїти null
до LastName
- за допомогою !
оператора. Тому що null!
не є null - наскільки компілятор стурбований нульовою безпекою.
!
є оператором , що прощає нуль , кажучи компілятору, що, хоча він зазвичай цього не дозволяє, він повинен виглядати в інший бік і дозволяти це в будь-якому випадку, тому що ми знаємо краще.null!
сам по собі мало практичного використання, оскільки все це, але заперечує корисність онульованих типів посилань. Це корисніше, коли ви знаєте, що вираз не може бутиnull
, але компілятор - ні.