可以在C#中重载`??`运算符?

时间:2012-09-11 08:19:51

标签: c# operators null-coalescing-operator

关于运算符重载,我读了这个MSDN document

在该示例中,使用的运算符为+-,还可以定义其他*/

我想重载??运算符以用于

之类的字符串
string emptyString = emptyString ?? "OtherValue";

而不是

string emptyString = string.IsNullOrEmpty(emptyString) ? "OtherValue" : emptyString;

想要将字符串转换为对象并使用??进行比较。

我知道??用于可空值的类型,MSDN说:

  

?? operator被称为null-coalescing运算符,用于为可空值类型或引用类型定义默认值。

     

如果操作数不为空,则返回左侧操作数;否则它返回正确的操作数。

我想问你是否可能在C#中重载此运算符。当需要使用??时,上面的示例很简单。

3 个答案:

答案 0 :(得分:7)

不,你不能。

一个简单的解决方法是使用扩展方法:

 public static string IfNullOrEmpty(this string instance, string alt){
   return string.IsNullOrEmpty(instance) ? alt : instance;
 }

 var str1 = "".IfNullOrEmpty("foo"); //'foo'
 var str2 = ((string)null).IfNullOrEmpty("bar"); //'bar'
 var str3 = "Not null or empty".IfNullOrEmpty("not used"); //'not null or empty'

虽然我注意到我发现为了使扩展方法出现在诸如""的一流编译时常量上,你需要将该扩展方法合并到System;即:

 namespace System {
   public static class MyStringExtensions { 
     // method here
   }
 }

不要这样做 - 只是为了解决

可能 - 虽然我不推荐它 - 为String编写一个包装器类型,它包含来自string的隐式强制转换运算符,返回null如果字符串为空 - 因此在该类型的实例上使用??运算符将产生正确的行为:

    public class FakeString
    {
        private string _source;
        public FakeString(string source)
        {
        }

        public static implicit operator string(FakeString instance)
        {
            return string.IsNullOrEmpty(instance._source) ? null : instance._source;
        }

        public static implicit operator FakeString(string source)
        {
            return new FakeString(source);
        }
    }

    [TestMethod]
    public void Test()
    {
        FakeString fs = "";
        string result = (string)fs ?? "foo";

        Assert.AreEqual("foo", result);
    }

但是,你有没有看到 - 你必须使用转换开始转换,真的很丑陋和可怕,好吧,就是不要这样做。但你可以不会。

我是否还需要免责声明?

关于该明确演员的一点注释

我的很大一部分人认为string result = fs ?? foo;应该有效,但事实并非如此。原因是由null执行的??检查仅在左侧的引用上 - 除了可空值类型的情况外,它的类型不可知。对IL进行反编译,将引用简单地加载到堆栈上,然后检查它是否计算为true或false,代码在该点分支为另外两个将值加载到堆栈的操作之一(这是{然后调用{1}}运算符。对于可以为null的值类型,此行为是不同的 - 编译器知道这些行为,因此相应地更改其行为。

答案 1 :(得分:6)

没有。请看这里Overloadable Operators C#。部分'这些运营商不能超载。'

答案 2 :(得分:2)

Acc to this你不能超载?操作