1

我阅读了有关运算符重载的MSDN 文档。

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

我想重载??运算符以用于字符串,例如

string emptyString = emptyString ?? "OtherValue";

代替

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

不想将字符串转换为对象并使用??.

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

这 ??运算符称为空值合并运算符,用于为可空值类型或引用类型定义默认值。

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

我想问你是否可以在 C# 中重载这个运算符。上面的例子是需要使用时的简单情况??

4

3 回答 3

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; IE:

 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,将引用简单地加载到堆栈上,然后检查它的计算结果是真还是假,代码在该点分支到将值加载到堆栈上的两个进一步操作之一(这是FakeString运算符然后被调用)。对于可为空的值类型,这种行为是不同的——编译器知道这些,因此会相应地改变它的行为。

于 2012-09-11T08:24:00.897 回答
6

不,请看这里Overloadable Operators C#。'这些运算符不能重载。

于 2012-09-11T08:20:54.767 回答
2

根据这个你不能超载??操作员。

于 2012-09-11T08:21:33.240 回答