为什么空传播不一致地传播为空<T>?



我特别提请注意空传播,因为它与bool?bool返回方法的使用有关。例如,请考虑以下事项:

public static bool IsAttributedWith<TAttribute>(this JsonProperty property) 
    where TAttribute : Attribute
{
    return property?.AttributeProvider
                    .GetAttributes(typeof(TAttribute), false)
                    .Any();
}

这不会编译,并且存在以下错误:

不能隐式地将布尔值?转换为布尔值。存在显式转换(是否缺少强制转换)?

这意味着它将该方法的整个主体视为bool?,因此我假设我可以在.Any()之后说.GetValueOrDefault(),但这是不允许的,因为.Any()返回bool而不是bool?

我知道我可以做以下任一工作作为解决方法:

public static bool IsAttributedWith<TAttribute>(this JsonProperty property) 
    where TAttribute : Attribute
{
    return property?.AttributeProvider
                    .GetAttributes(typeof(TAttribute), false)
                    .Any()
        ?? false;
}

public static bool IsAttributedWith<TAttribute>(this JsonProperty property) 
    where TAttribute : Attribute
{
    var any = 
        property?.AttributeProvider
                 .GetAttributes(typeof(TAttribute), false)
                 .Any();
     return any.GetValueOrDefault();
}

public static bool IsAttributedWith<TAttribute>(this JsonProperty property) 
    where TAttribute : Attribute
{
    return property?.AttributeProvider
                    .GetAttributes(typeof(TAttribute), false)
                    .Any()
        ?? false;
}

我的问题是,为什么我不能在.Any()调用上直接调用.GetValueOrDefault()链接?

public static bool IsAttributedWith<TAttribute>(this JsonProperty property) 
    where TAttribute : Attribute
{
    return (property?.AttributeProvider
                    .GetAttributes(typeof(TAttribute), false)
                    .Any())
                    .GetValueOrDefault();
}

我认为这是有道理的,因为此时值实际上是bool?的,而不是bool.

在运算符?.之后,所有以下调用链都被解释为条件,而不仅仅是立即调用。所以,这段代码:

property?.AttributeProvider
         .GetAttributes(typeof(TAttribute), false)
         .Any()

解释为

property==null ? (bool?)null : property.AttributeProvider
                                       .GetAttributes(typeof(TAttribute), false)
                                       .Any()

如果添加GetValueOrDefault()

property==null ? (bool?)null : property.AttributeProvider
                                       .GetAttributes(typeof(TAttribute), false)
                                       .Any()
                                       .GetValueOrDefault()

它会失败,因为Any()返回boolbool?.因此,您需要在此处使用括号:

(property==null ? (bool?)null : property.AttributeProvider
                                        .GetAttributes(typeof(TAttribute), false)
                                        .Any())
                                        .GetValueOrDefault()

使用运算符时需要使用?.括号:

(property?.AttributeProvider
          .GetAttributes(typeof(TAttribute), false)
          .Any())
          .GetValueOrDefault()

GetValueOrDefault 调用在返回 Any() 方法时执行,该方法返回一个 bool 。 如果要执行整个主体的结果,则必须将其括在括号中。

 return (property?.AttributeProvider
                .GetAttributes(typeof(TAttribute), false)
                .Any())
                .GetValueOrDefault();

null 条件运算符是一个短路运算符,因此,如果对象为 null,则不会执行尝试在对象上执行的点右侧的任何内容或其任何属性或方法。因此,为了在整个语句上执行代码,您必须以某种方式包装它(括号或使用其他对象)。

相关内容

  • 没有找到相关文章

最新更新