5

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

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

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

不能隐式转换布尔?布尔值。存在显式转换(您是否缺少演员表)?

这意味着它将方法的整个主体视为 a bool?,因此我假设我可以.GetValueOrDefault()在 the 之后说,.Any()但这不允许作为.Any()return boolnot 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;
}

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

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

我认为这是有道理的,因为价值实际上是bool?在这一点上,而不是bool.

4

2 回答 2

6

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

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()return boolnot bool?。因此,您需要在此处使用括号:

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

使用运算符时需要使用相同的括号?.

(property?.AttributeProvider
          .GetAttributes(typeof(TAttribute), false)
          .Any())
          .GetValueOrDefault()
于 2017-01-20T02:50:37.633 回答
2

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

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

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

于 2017-01-20T02:28:29.437 回答