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

Sna*_*yes 1 c# operators null-coalescing-operator

我阅读了关于运算符重载的MSDN文档.

在该示例中,所使用的经营者+,-并且还可以定义其他*/.

我想重载??运算符用于字符串之类的

string emptyString = emptyString ?? "OtherValue";
Run Code Online (Sandbox Code Playgroud)

代替

string emptyString = string.IsNullOrEmpty(emptyString) ? "OtherValue" : emptyString;
Run Code Online (Sandbox Code Playgroud)

希望将字符串转换为对象并使用比较??.

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

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

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

我想问你是否有可能在C#中重载此运算符.以上示例是需要使用时的简单情况??.

And*_*tan 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'
Run Code Online (Sandbox Code Playgroud)

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

 namespace System {
   public static class MyStringExtensions { 
     // method here
   }
 }
Run Code Online (Sandbox Code Playgroud)

不要这样做 - 但只是为了踢

可以 - 虽然我不推荐它 - 编写一个包装类型,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);
    }
Run Code Online (Sandbox Code Playgroud)

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

我还需要更多免责声明吗?

关于那个明确演员的一点注意事项

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


pet*_*kyy 6

不.请看一下这里的Overloadable Operators C#.部分'这些运营商不能超载'.