#c# #c#-8.0
Вопрос:
Я попытался использовать этот прощающий нуль оператор (!) в Unity 2020.3.1f1 с vscode. Ни один из этих инструментов не видел, как работает этот синтаксис, поэтому я воспроизвел его в этих двух скрипках, вдохновленных документами:
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-forgiving
Один и тот же код для обоих:
using System;
public class Program
{
#nullable enable
public struct Person {
public string name;
}
static Person? GetPerson(bool yes) {
Person ret = new Person();
ret.name = "coucou";
if(yes) return ret;
else return null;
}
public static void Main()
{
Person? person = GetPerson(true);
if(person != null) Console.WriteLine("name: " person!.name);
}
}
Сначала с C# 7.3 не работает должным образом, как ожидалось: https://dotnetfiddle.net/HMS35M
Во-вторых, с C# 8.0, по крайней мере, просто игнорируя синтаксис, кажется: https://dotnetfiddle.net/Mhbqhk
Есть идеи, как сделать так, чтобы это второе сработало?
Комментарии:
1. Это работает. Опубликуйте свой код в самом вопросе
2. @PanagiotisKanavos готово
3. @HansKilian Первое очевидно из сообщения, второе-8 или 9 после этого: docs.microsoft.com/en-us/dotnet/csharp/language-reference/…
Ответ №1:
Оператор, прощающий нуль , не применяется к Nullable<T>
— остаются только доступные соответствующие элементы .Value
, .HasValue
и .GetValueOrDefault()
; вам придется использовать немного более длинное person.Value.name
/ person.GetValueOrDefault().name
, или вы могли бы зафиксировать значение во время if
теста:
if (person is Person val) Console.WriteLine("name: " val.name);
Комментарии:
1. спасибо за изучение этого нового синтаксиса, одна строка сохранена для приведения!
Ответ №2:
Оператор, прощающий нуль(Черт возьми), позволяет вам уведомлять компилятор о том, что он должен игнорировать возможную нулевую ссылку, потому что у вас больше информации, чем у компилятора.
Сначала с C# 7.3 не работает должным образом, как ожидалось: https://dotnetfiddle.net/HMS35M
Это null-forgiving operator
не было реализовано до C# 8.0, вам понадобится пакет nuget или какой-либо альтернативный обходной путь, чтобы использовать символ взрыва в этом контексте для C#7.3.
Есть идеи, как сделать так, чтобы это второе сработало?
При использовании a Nullable<T>
struct
вы можете использовать .Value
свойство для получения значения объекта(фактического Person
struct
, определенного вами). Без .Value
метода компилятор не знает, пытаетесь ли вы получить доступ к Nullable<T>
объекту или struct
к определенному вами объекту. Поэтому он не может найти .name
поле на Nullable<T>
объекте.
Это должно сработать для вас
if (person != null) Console.WriteLine("name: " person!.Value.name);