【问题标题】:Possible to overload null-coalescing operator?可能重载空合并运算符?
【发布时间】:2010-09-25 19:57:04
【问题描述】:

是否可以为 C# 中的类重载 null 合并运算符?

例如,如果实例为空,我想返回一个默认值,如果不是,则返回该实例。代码看起来像这样:

   return instance ?? new MyClass("Default");  

但是如果我想使用 null-coalescing 运算符来检查 MyClass.MyValue 是否已设置呢?

【问题讨论】:

  • Patrik,一个用途:我想重载字符串的空合并运算符以将空视为空。这是否明智或其他,这是一个不同的问题。

标签: c# .net operator-overloading null-coalescing-operator


【解决方案1】:

简单的答案:没有

C# 设计原则不允许改变语言语义的运算符重载。因此复合赋值、三元运算符、...等复杂运算符不能重载。

【讨论】:

    【解决方案2】:

    好问题!它没有在list of overloadable and non-overloadable operators 中以一种或另一种方式列出,the operator's page 上也没有提到任何内容。

    所以我尝试了以下方法:

    public class TestClass
    {
        public static TestClass operator ??(TestClass  test1, TestClass test2)
        {
            return test1;
        }
    }
    

    我收到错误“预期可重载的二进制运算符”。所以我想说,从 .NET 3.5 开始,答案是不。

    【讨论】:

    【解决方案3】:

    根据ECMA-334 标准,不能超载??操作员。

    同样,您不能重载以下运算符:

    • =
    • &&
    • ||
    • ?:
    • ?.
    • 已检查
    • 未选中
    • 类型
    • 作为

    【讨论】:

      【解决方案4】:

      如果有人在这里寻找解决方案,最接近的例子就是这样做

      return instance.MyValue != null ? instance : new MyClass("Default");
      

      【讨论】:

      • -1:你没有抓住重点,你已经可以用 OP 的代码做你建议的事情了......也请仔细阅读这个问题,他不是在问如何做到这一点,但如果可能的话重载空合并运算符 - 不幸的是,它不是。
      • 我知道他问的是关于超载 ??接线员和我读了回复说这是不可能的。因此,我只是为任何可能遇到此页面并寻找可行的东西的人提供了一个可以达到预期结果的解决方案(假设它不使用 ?? 运算符)。
      • +1:因为它是相关的,并且清楚地表明这不是一个真正的答案,而是一个紧密的例子
      • @Jaap - 如果instance 为空,则会抛出 NullReferenceException。你需要它是(instance != null && instance.MyValue != null) ? instance : new MyClass("Default");
      【解决方案5】:

      据传这是下一版 C# 的一部分。来自http://damieng.com/blog/2013/12/09/probable-c-6-0-features-illustrated

      7.一元空值检查

      无需在访问属性或方法之前检查空值。在 Groovy 中称为安全导航运算符)。

      之前

      if (points != null) {
          var next = points.FirstOrDefault();
          if (next != null && next.X != null) return next.X;
      }   
      return -1;
      

      之后

      var bestValue = points?.FirstOrDefault()?.X ?? -1;
      

      【讨论】:

        【解决方案6】:

        我试图通过我编写的与Nullable<T> 非常相似的结构来实现这一点。使用Nullable<T>,您可以执行类似的操作

        Nullable<Guid> id1 = null;
        Guid id2 = id1 ?? Guid.NewGuid();
        

        id1Nullable&lt;Guid&gt; 隐式转换为Guid 没有问题,尽管Nullable&lt;T&gt; 只有defines an explicit conversion 才能键入T。用我自己的类型做同样的事情,它给出了一个错误

        运算符'??'不能应用于“MyType”类型的操作数和 '指导'

        所以我认为编译器内置了一些魔法,可以为Nullable&lt;T&gt; 设置一个特殊例外。所以作为一种选择......

        tl;博士

        我们不能覆盖 ?? 运算符,但是如果您希望合并运算符评估基础值而不是类(或在我的情况下为结构)本身,您可以只使用导致很少额外的方法需要击键。在我上面的案例中,它看起来像这样:

        public struct MyType<T>
        {
            private bool _hasValue;
            internal T _value;
        
            public MyType(T value)
            {
                this._value = value;
                this._hasValue = true;
            }
        
            public T Or(T altValue)
            {
                if (this._hasValue)
                    return this._value;
                else
                    return altValue;
            }
        }
        

        用法:

        MyType<Guid> id1 = null;
        Guid id2 = id1.Or(Guid.Empty);
        

        这很好用,因为它是一个结构,id1 本身实际上不能为空。对于一个类,如果实例为空,只要您尝试检查的值是公开的,扩展方法就可以处理:

        public class MyClass
        {
            public MyClass(string myValue)
            {
                MyValue = myValue;
            }
        
            public string MyValue { get; set; }
        }
        
        public static class MyClassExtensions
        { 
            public static string Or(this MyClass myClass, string altVal)
            {
                if (myClass != null && myClass.MyValue != null)
                    return myClass.MyValue;
                else
                    return altVal;
            }
        }
        

        用法:

        MyClass mc1 = new MyClass(null);
        string requiredVal = mc1.Or("default"); //Instead of mc1 ?? "default";
        

        【讨论】:

          猜你喜欢
          • 2016-06-14
          • 2012-09-19
          • 1970-01-01
          • 1970-01-01
          • 2013-09-13
          • 1970-01-01
          • 2013-06-11
          • 2015-03-27
          • 2023-03-23
          相关资源
          最近更新 更多