如果方法完全返回,则指定 NotNull

Posted

技术标签:

【中文标题】如果方法完全返回,则指定 NotNull【英文标题】:Specify NotNull If Method Returns At All 【发布时间】:2020-02-05 08:21:38 【问题描述】:

我正在使用来自 C# 8 的新可空引用类型,我想知道如果方法返回,是否可以指示传入的参数不为空。

我找到了[NotNullIf][DoesNotReturnIf],但它们似乎分别触发了方法的返回值和特定的bool 参数。

这是我目前拥有的:

public static bool RaiseIfNull([NotNullWhen(true)] object? thing) => RaiseIf(() => thing is null);
public static bool RaiseIf(Func<bool> predicate)

  if (predicate()) throw new HttpException(400);
  return true;

这看起来不错,但是当我调用它时 - 我仍然看到警告。 (我也试过RaiseIfNull([NotNullIfNotNull("thing")] object? thing),但没用。)

[HttpPost("id")]
public async Task Etc(string id, [FromBody] Dto data)

  HttpException.RaiseIfNull(data?.property);
  await DoEtc(id, data.property)); // warning here

我是否遗漏了一些明显的东西?

【问题讨论】:

这并不完全是您所需要的,但我认为值得注意的是,对于类型参数,有 where T : notnull 约束。类型参数必须是不可为空的类型。参数可以是 C# 8.0 或更高版本中的不可为空的引用类型,也可以是不可为空的值类型。此约束也适用于任何类、接口、委托或数组类型。 【参考方案1】:

使用正常的空检查

首先,RaiseIfNull 提供的不仅仅是:

var value=data?.property ?? new HttpException(400);

编译器可以识别的。另一方面,RaiseIfNull 隐藏了实际情况。此代码不会产生警告:

class D

    public string? propertyget;set;



D? data=null;
var value=data?.property ?? throw new HttpException(400);
Console.WriteLine(value.Length);

无条件后置条件和泛型

也就是说,要使用的正确参数是NotNull - 在方法执行后,即使类型本身可以为空,参数也不为空。该属性可以应用于:

参数 属性 字段和 返回值

这些方法也可以是通用的,以避免将结构装箱到对象中。为此,我们需要指定类型是类还是结构,因为生成的具体类型非常不同 - string? 仍然是字符串,而 int?Nullable&lt;int&gt;

public static bool RaiseIfNull<T>([NotNull] T? thing) 
    where T:class
    => RaiseIf(() => thing is null);

public static bool RaiseIfNull<T>([NotNull] T? thing) 
    where T:struct
    => RaiseIf(() => thing is null);

鉴于这些方法,以下代码也不会生成警告:

D? data=null;
RaiseIfNull(data?.property);
Console.WriteLine(data.property.Length);

最后,我们可以去掉返回值了:

public static void RaiseIfNull<T>([NotNull] T? thing) 
    where T:class
    => RaiseIf(() => thing is null);

public static void RaiseIfNull<T>([NotNull] T? thing) 
    where T:struct
    => RaiseIf(() => thing is null);

【讨论】:

RaiseIfNull() 有意义且有用,如果此方法创建复杂的失败消息或异常对象,并且如果在多个位置执行检查。 en.wikipedia.org/wiki/Don%27t_repeat_yourself

以上是关于如果方法完全返回,则指定 NotNull的主要内容,如果未能解决你的问题,请参考以下文章

九方法的使用

字符筛选

SQL case 语句:如果为空则返回指定的字符串,否则返回选择值

c# IeNumerable 如果没有则返回[重复]

Python ljust()方法

JAVA入门之方法