Null-forgiving 运算符 (!) 在 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

有什么想法可以使第二个工作正常进行吗?

解决方法

null-forgiving 运算符不适用于 $dateforlookup = (Get-Date).AddDays(-1) $DC_GC = "test1.com" $DC_PL = "test2.com" $OU_GC = "some OU1" $OU_PL = "some OU2" $user_GC = Get-ADUser -Server $DC_GC -SearchBase $OU_GC -Filter * -Properties GivenName,Surname,GABCustomUser3,whenCreated,Title,Department | Where {$_.whenCreated -gt $dateforlookup} $user_PL = Get-ADUser -Server $DC_PL -SearchBase $OU_PL -Filter * -Properties mail if ($user_GC.GABCustomUser3 -ne $user_PL.mail) { $output = foreach ($user in $user_GC) { $properties = @{ 'FirstName' = $user.GivenName 'LastName' = $user.Surname.Substring(0,1)+($user.Surname.Substring(1).tolower()) 'Email' = $user.GABCustomUser3 'Department' = $user.Department 'JobTitle' = $user.Title 'Organization' = $user.Organization 'GUID'= ($user.GivenName.ToLower()).Substring(0,1)+'.'+$user.Surname.ToLower() } New-Object -Type psobject -Property $properties $NewUserExists = $true } Write-Host "New user found" } - 唯一可用的相关成员仍然是 Nullable<T>.Value.HasValue;您必须使用稍长的 .GetValueOrDefault() / person.Value.name,否则您可以在 person.GetValueOrDefault().name 测试期间捕获该值:

if
,

null-forgiving operator(Damn it) 运算符允许您通知编译器它应该忽略可能为空的引用,因为您拥有比编译器更多的信息。

首先,C# 7.3 没有按预期工作:https://dotnetfiddle.net/HMS35M

直到 C# 8.0 才实现 null-forgiving operator,您需要一个 nuget 包或一些替代的解决方法来在 C#7.3 的上下文中启用爆炸符号。

有什么想法可以使第二个工作正常进行吗?

当使用 Nullable<T> struct 时,您可以使用 .Value 属性来获取对象的值(您定义的实际 Person struct)。如果没有 .Value 方法,编译器不知道您是在尝试访问 Nullable<T> 对象还是您定义的 struct 对象。所以它在 .name 对象上找不到 Nullable<T> 字段。

这应该对你有用

if (person != null) Console.WriteLine("name: " + person!.Value.name);