【问题标题】:C# 8 Nullable Reference Types Nested Guard [duplicate]C# 8 可空引用类型嵌套保护 [重复]
【发布时间】:2020-11-30 14:32:57
【问题描述】:

我最近更新了一个项目以利用 C# 8 可空引用类型功能。解决方案中的所有内容都按预期工作,除了一个自定义 Guard 类,该类是为了减少创建 Guard 表达式时所需的击键次数而编写的。下面是 Guard 类的一个基本示例:

public static partial class Guard
{
    public static void AgainstNull(object? value)
    {
        if (value == null)
        {
            throw new ArgumentNullException("The value can not be null");
        }
    }
}

这里是测试类:

public class Test
{
    public object? Data { get; set; }

    public void TestMethod()
    {
        Guard.AgainstNull(Data);

        //if (Data == null)
        //{
        //    throw new ArgumentNullException("Data can not be null.");
        //}

        var text = Data.ToString();
    }
}

尝试使用 Guard 类会导致“取消引用可能为空的引用”错误:

但是,如果我使用传统的保护表达式(if (Data == null)),编译器会足够聪明地推断出 Data 属性不会为 null:

public class Test
{
    public object? Data { get; set; }

    public void TestMethod()
    {
        //Guard.AgainstNull(Data);

        if (Data == null)
        {
            throw new ArgumentNullException("Data can not be null.");
        }

        var text = Data.ToString();
    }
}

是否可以将嵌套表达式/保护语句与 C# 8 可空引用类型功能一起使用?

谢谢!

【问题讨论】:

  • 不确定这是否可行,我在移动设备上,但试试var text = Data.ToString()!; ?在 ToString() 之后使用 !。试一试。我认为它被称为 null 抑制运算符。然后,您可以在您的测试类中像这样实例化它:Guard.AgainstNull(Data!); 或像我上面建议的那样使用它。
  • 现在我想了想,你应该做Data!.ToString();,因为你想确保 Data 不为空。 ! 对运行时没有影响(这是一件好事 :)),它只影响静态评估。在运行时,表达式 Data! 的计算结果为基础表达式 Data 的结果。如果它对您有帮助,请告诉我,我可以在使用计算机后写出更详细的答案。
  • @Joel,对于回复缓慢,我深表歉意。所以自动关闭了我的问题,因为它已经在这里得到了回答:stackoverflow.com/questions/58279704/…这个答案就是我想要的。我将 [NotNull] 属性添加到我的 Guard 类中,静态分析开始按预期工作。

标签: c# types reference nullable guard


【解决方案1】:

调用 Data.ToString(); 时应该可以使用空条件运算符;

var text = Data?.ToString()

【讨论】:

    【解决方案2】:

    如果您正在寻找与if (Data == null) 等效的方法。

    您可以简单地在您的对象上使用!(null-forgiving/null 抑制运算符)

    (在 C# 8.0 中引入)

    如果您熟悉 TypeScript 等语言,您就会熟悉它的含义。如果没有,这里有一个简要说明:

    • 对运行时没有影响。
    • 仅影响编译器的静态流分析。
    • Data! 在运行时计算为 Data 的底层表达式的结果。

    因此,在您的情况下,您应该能够执行以下任一操作:

    Guard.AgainstNull(Data!);
    

    或者

    var text = Data!.ToString();
    

    这是您的示例之后的示例,以进一步说明

    #nullable enable
    public static partial class Guard
    {
        public Guard(object? value) => Value = value ?? throw new ArgumentNullException(nameof(value));
    
        public object? Value { get; }
    }
    
    
    public class Test
    {
        public object? Data { get; set; }
        public void TestMethod()
        { 
             Guard(Data!);
             var text = Data!.ToString();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2018-07-18
      • 1970-01-01
      • 2011-09-22
      • 1970-01-01
      • 1970-01-01
      • 2011-08-15
      • 2010-09-23
      • 1970-01-01
      相关资源
      最近更新 更多