代码之家  ›  专栏  ›  技术社区  ›  The Chairman

成员访问运算符(.)的优先级是否高于空条件成员访问运算符(?)?

  •  2
  • The Chairman  · 技术社区  · 6 年前

    我想我们都同意空条件成员访问操作符 ?.

    using System.Collections.Generic;
    
    public class MyClass
    {
        public void DoSomething(Foo foo)
        {
            var knownIndices = new[] { 42 };
            bool overlaps;
    
            // might throw a null reference exception
            overlaps = foo.Indices.Overlaps(knownIndices);
    
            // how I used to do it
            overlaps = foo != null && foo.Indices != null && foo.Indices.Overlaps(knownIndices);
    
            // with null conditional member access (won't compile)
            //overlaps = foo?.Indices?.Overlaps(knownIndices).GetValueOrDefault();
    
            // with null conditional member access (using local variable)
            bool? overlapsOrIsIndeterminable = foo?.Indices?.Overlaps(knownIndices);
            overlaps = overlapsOrIsIndeterminable.GetValueOrDefault();
    
            // with null conditional member access (inlined)
            overlaps = (foo?.Indices?.Overlaps(knownIndices)).GetValueOrDefault();
    
            // with null conditional member access and null-coalescing
            overlaps = foo?.Indices?.Overlaps(knownIndices) ?? false;
        }
    
        public class Foo
        {
            public HashSet<int> Indices;
        }
    }
    

    为什么要在链式表达式中使用括号? ?.Overlaps() 很明显,计算结果是一个可为null的bool,正如我们在使用局部变量的示例中所看到的,所以我希望 .GetValueOrDefault()

    The C# language reference 声明成员访问运算符 . ?.

    . ?. ?

    2 回复  |  直到 6 年前
        1
  •  4
  •   ikkentim    6 年前

    做。尽管在语言参考中陈述了什么,但它的优先顺序比?。?

    空条件运算符是一种特殊情况。正如戴夫所解释的,任何连续的表达式 ?. null . 如果包含 ?. 运算符通常会求值为原始值(例如 int ),它将实际评估为 Nullable<int> 值,但这个值是

    foo.GetIntValue() 退货 内景 , foo?.GetIntValue() 退货 . 如果附加到此表达式,则“target”值的类型为 内景 . 因此以下代码不会编译,因为 GetValueOrDefault 是…的成员 可为空<内部> ,不属于 内景 .

    foo?.GetIntValue().GetValueOrDefault(); // ERROR
    

    因为 表达式的计算结果为 可为空<内部> GetValue或默认值

    (foo?.GetIntValue()).GetValueOrDefault();
    

    注意:您可以将此运算符与 null-coalescing operator

    foo?.GetIntValue() ?? 1; // If foo is null, this expression will evaluate to 1