什么是 ?[]?C#中的语法?



当我在研究委托时,它实际上是Delegate.cs中的抽象类,我看到了以下我不明白的方法

  • 为什么返回值使用?尽管它已经是引用((类型
  • 参数?[]?含义

你能解释一下吗?

public static Delegate? Combine(params Delegate?[]? delegates)
{
if (delegates == null || delegates.Length == 0)
return null;
Delegate? d = delegates[0];
for (int i = 1; i < delegates.Length; i++)
d = Combine(d, delegates[i]);
return d;
}

分步说明:

params Delegate?[] delegates- 它是一个可为空的Delegate数组

params Delegate?[]? delegates- 整个数组可以为空

由于每个参数都是Delegate?类型,并且您返回Delegate?[]?数组的索引,因此返回类型是有意义的Delegate?否则编译器将返回错误,就好像您正在从返回字符串的方法重新和int一样。

例如,您可以更改代码以返回如下所示的Delegate类型:

public static Delegate Combine(params Delegate?[]? delegates)
{
Delegate defaulDelegate = // someDelegate here
if (delegates == null || delegates.Length == 0)
return defaulDelegate;
Delegate d = delegates[0] ?? defaulDelegate;
for (int i = 1; i < delegates.Length; i++)
d = Combine(d, delegates[i]);
return d;
}

可为空的引用类型是 C# 8.0 中的新增类型,以前不存在。

这是一个文档问题,以及如何在编译时生成警告。

异常"对象未设置为对象的实例"异常很常见。 但这是一个运行时异常,它已经在编译时部分发现。

对于调节Delegate d您可以随时致电

d.Invoke();

这意味着,你可以对它进行编码,在编译时什么都不会发生。它可能会在运行时引发异常。

而对于本代码的新Delegate? p

p.Invoke();

将生成编译器警告。CS8602: Dereference of a possibly null reference除非你写:

p?.Invoke();

什么意思,仅在不为空时才调用。

因此,您记录了一个变量可能包含 null 或不包含 null。它可以更早地引发警告,并且可以避免多次测试 null。与 int 和 int 相同?。您肯定知道,一个不是空的 - 并且您知道如何将一个转换为另一个。

在 C# 8 中,应显式将引用类型标记为可为空。

默认情况下,这些类型不能包含 null,有点类似于值类型。虽然这不会改变幕后的工作方式,但类型检查器将要求您手动执行此操作。

给定的代码经过重构以使用 C# 8,但它不会从此新功能中受益。

public static Delegate? Combine(params Delegate?[]? delegates)
{
// ...[]? delegates - is not null-safe, so check for null and emptiness
if (delegates == null || delegates.Length == 0)
return null;
// Delegate? d - is not null-safe too
Delegate? d = delegates[0];
for (int i = 1; i < delegates.Length; i++)
d = Combine(d, delegates[i]);
return d;
}

下面是利用此功能的更新代码(不起作用,只是一个想法(的示例。它使我们免于空检查,并稍微简化了此方法。

public static Delegate? Combine(params Delegate[] delegates)
{
// `...[] delegates` - is null-safe, so just check if array is empty
if (delegates.Length == 0) return null;
// `d` - is null-safe too, since we know for sure `delegates` is both not null and not empty
Delegate d = delegates[0];
for (int i = 1; i < delegates.Length; i++)
// then here is a problem if `Combine` returns nullable
// probably, we can add some null-checks here OR mark `d` as nullable
d = Combine(d, delegates[i]);
return d;
}

最新更新