简体   繁体   English

C# 是否有某种 value_or_execute 或 value_or_throw?

[英]Does C# have some kind of value_or_execute or value_or_throw?

I'm learning C# and trying to handle the influx of " a could be null " warnings.我正在学习 C# 并尝试处理“ a可能是null ”警告的涌入。

I was wondering, since it's such a common case to error out when something is null, either by returning from the function or throwing an exception, does C# have some kind of syntactical sugar for that case?我想知道,由于从 function 返回或抛出异常,当某些东西是 null 时出错是很常见的情况,那么 C# 是否对这种情况有某种语法糖?

Example of what I have in mind: int a = obtainA()??? { Console.WriteLine("Fatal error;") return };我想到的例子: int a = obtainA()??? { Console.WriteLine("Fatal error;") return }; int a = obtainA()??? { Console.WriteLine("Fatal error;") return }; (this is not real code) (这不是真正的代码)

I know about the ??我知道?? and ??= operators, but they don't seem to help much here and I haven't found better.??=运算符,但它们在这里似乎没有多大帮助,我也没有找到更好的方法。

If not, what would be the closest we have to emulating this?如果不是,我们最接近模仿的是什么? Is there no better way than to write the following?有没有比下面这样写更好的方法了?

int? nullableA = obtainA();
int a;
if (nullableA.HasValue) {
    a = nullableA.Value;
}
else {
    Console.WriteLine("Fatal error");
    return;
}
/* use a, or skip defining a and trust the static analyzer to notice nullableA is not null */

"or_throw" can be achieved with ?? “or_throw”可以用??实现operator since C# 7 due to throw expressions introduction: operator since C# 7 由于抛出表达式介绍:

int? i = null;
int j = i ?? throw new Exception();

Another throw approach can be achieved with ArgumentNullException.ThrowIfNull :可以使用ArgumentNullException.ThrowIfNull实现另一种抛出方法:

#nullable enable
int? i = null;
ArgumentNullException.ThrowIfNull(i);
int j = i.Value; // no warning, compiler determine that i can't be null here

Also you can write your own method supporting nullable flow analysis (like ArgumentNullException.ThrowIfNull does) with attributes for null-state static analysis interpreted by the C# compiler :您还可以编写自己的方法来支持可空流分析(如ArgumentNullException.ThrowIfNull所做的那样),其中包含由 C# 编译器解释的空状态 static 分析的属性

#nullable enable
int? i = null;
if (IsNullAndReport(i)) return;
int j = i.Value; // no warning, compiler determine that i can't be null here

bool IsNullAndReport([NotNullWhen(false)]int? v, [CallerArgumentExpression(nameof(i))] string name = "")
{
    if (v is null)
    {
        Console.WriteLine($"{name} is null;");
        return true;
    }

    return false;
}

And pattern matching approach:和模式匹配的方法:

int? i = null;
if (i is { } j) // checks if i is not null and assigns value to scoped variable 
{
    // use j which is int
}
else
{
    Console.WriteLine("Fatal error");
    return;
}

The ?? ?? operator is often used for this, particularly in parameter null tests:运算符通常用于此,特别是在参数 null 测试中:


public class A
{
   private readonly string _firstArg;
   private readonly string _secondArg;
   public A(string firstArg, string secondArg)
   {
      _firstArg = firstArg ?? throw new ArgumentNullException(nameof(firstArg));
      _secondArg = secondArg ?? throw new ArgumentNullException(nameof(secondArg));
   }
}

This throws an exception if the passed parameter was null, ensuring that the field values will never be null (and thus not requiring any further null tests anywhere else in the class).如果传递的参数是 null,这将引发异常,确保字段值永远不会是 null(因此不需要在类中的其他任何地方进行任何进一步的 null 测试)。

There is also a static helper method for this: ArgumentNullException.ThrowIfNull() :为此还有一个 static 辅助方法: ArgumentNullException.ThrowIfNull()

int? nullableA = null;
ArgumentNullException.ThrowIfNull(nullableA);

This will throw:这将抛出:

ArgumentNullException: Value cannot be null. (Parameter 'nullableA') ArgumentNullException:值不能为 null。(参数“nullableA”)

It uses the new CallerArgumentExpressionAttribute to auto-magically add the name of the variable in question to the error message.它使用新的CallerArgumentExpressionAttribute自动神奇地将相关变量的名称添加到错误消息中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM