模式匹配优先于引用还是值相等?

Che*_*ron 6 c# pattern-matching c#-7.0

我看到很多关于如何在 C#7 中使用模式匹配的例子。这一切看起来都不错。但是,我有一个问题,我似乎无法找到答案。

假设您有以下表达式:

if (a is null)
Run Code Online (Sandbox Code Playgroud)

我的问题是:在 C#7 中是否更喜欢使用模式匹配而不是引用或值相等?

所以而不是写:

if (a == null)
Run Code Online (Sandbox Code Playgroud)

或者:

if (a.Equals(null))
Run Code Online (Sandbox Code Playgroud)

或者:

if (object.Equals(a, null))
Run Code Online (Sandbox Code Playgroud)

我怀疑会a is null生成类似于最后一个表达式的内容。但一般来说,切换到模式匹配会更受欢迎吗?

如果我错了,请纠正我,这是一个主要基于意见的问题,但我似乎无法找到支持这一点的明确答案。

Dav*_*rno 4

考虑以下四个代码片段:

// 1
var x = "";
var y = x is null;

// 2
var x = "";
var y = x.Equals(null);

// 3
var x = "";
var y = object.Equals(x, null);

// 4
var x = "";
var y = x == null;
Run Code Online (Sandbox Code Playgroud)

它们的 IL 分别为:

// 1
IL_0001: ldstr ""
IL_0006: stloc.0
IL_0007: ldnull
IL_0008: ldloc.0
IL_0009: call bool [mscorlib]System.Object::Equals(object, object)
IL_000e: stloc.1

// 2
IL_0001: ldstr ""
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: ldnull
IL_0009: call bool [mscorlib]System.Object::Equals(object, object)
IL_000e: stloc.1

// 3 
IL_0001: ldstr ""
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: ldnull
IL_0009: call bool [mscorlib]System.Object::Equals(object, object)
IL_000e: stloc.1

// 4
IL_0001: ldstr ""
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: ldnull
IL_0009: ceq
IL_000b: stloc.1
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,前三个结果产生几乎相同的代码。该==版本使用ceq而不是.Equals().

我猜ceq速度更快,因此x == null是测试null. 除此之外,这变成了偏好风格的问题。

  • 另外,我认为您在检查 IL 时应该使用发布模式,这会导致代码更短(没有“stloc.0 ldloc.0”),并且可能会让您对代码的性能有更好的了解。 (3认同)