C#中使用is关键字声明变量内联

Use of is Keyword in C# to declare variable inline

我目前正在使用 v4.6.2 开发一个 C# 项目,Visual Studio 刚刚建议对以下代码进行代码更改。

我的问题是,我从未见过 is 关键字以这种方式创建新的变量实例。

原代码为:

var authInfo = inputs.FirstOrDefault(i =>
    typeof(SoapAuthenticationBase).IsAssignableFrom(i.GetType()));

if (authInfo is SoapAuthenticationBase)

Visual Studio 2017 年建议:

if (inputs.FirstOrDefault(i =>
        typeof(SoapAuthBase).IsAssignableFrom(i.GetType())) 
        is SoapAuthBase authenticationContract)

我查看了 Microsoft 关于 'is' keyword 的文档,但没有发现任何解释此语法的内容。

以这种方式'is'添加了什么版本的 C#?

虽然建议是创建一个新变量,但它的范围是 if(即更窄)。

var authInfo = inputs.FirstOrDefault(i =>
    typeof(SoapAuthenticationBase).IsAssignableFrom(i.GetType()));
if (authInfo is SoapAuthenticationBase){
   // authInfo exists
}
// authInfo exists

这基本上是建议您删除您正在声明的现有 authInfo 实例。

if (inputs.FirstOrDefault(i =>
        typeof(SoapAuthBase).IsAssignableFrom(i.GetType())) 
        is SoapAuthBase authenticationContract){
  // authenticationContract exists
}
// authenticationContract does not exist

在你的第一个 snipper 中,is 关键字检查左边的东西是否是右边类型的实例。 is return 是一个布尔值,FirstOrDefault 调用是 returning null 或 SoapAuthenticationBase 的一个实例,它被分配给您的变量。

正如@Ashley Medway 指出的那样,第二个代码片段实际上是 C# 模式匹配的示例。 authenticationContractSoapAuthBase 的一个实例,只有当左边的东西是它的一个实例时它才会有一个值。否则,整个语句将 return 为假。

也就是说,我个人认为您的原始代码更具可读性。我会倾向于忽略VS,让编译器稍后再解决。

此功能称为模式匹配,它是在版本 7 的 c# 语言中引入的。在您的示例中它不是很清楚,但请考虑以下 [= 的规范示例12=] 覆盖:

public override bool Equals(obj other)
{
    if (obj is Foo)
    {
        return Equals((Foo)obj);
    }

    return false;
}

这实际上是一种浪费,因为您要检查类型两次:一次是查看它是否确实是一个 Foo,然后在执行转换时再次检查。这似乎不必要地冗长。

模式匹配允许更简洁的语法:

public override bool Equals(obj other)
{
    if (obj is Foo foo)
    {
        return Equals(foo);
    }

    return false;
}

您可以阅读有关此功能的更多信息 here