在 C# 中使用 is 关键字以内联方式声明变量



我目前正在使用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"关键字的文档,没有发现任何解释这种语法的内容。

这种方式添加了哪个版本的 C#?

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

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;
}

您可以在此处阅读有关此功能的更多信息。

在你的第一个狙击手中,is 关键字检查左边的东西是否是右边类型的实例。 is返回布尔值,则FirstOrDefault调用返回 null 或分配给变量的 SoapAuthenticationBase 实例。

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

也就是说,我个人发现您的原始代码更具可读性。我倾向于忽略VS,让编译器稍后对其进行排序。

虽然建议正在创建一个新变量,但它的范围是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

最新更新