Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
可以在C#中重载“??”运算符?_C#_Operators_Null Coalescing Operator - Fatal编程技术网

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

可以在C#中重载“??”运算符?,c#,operators,null-coalescing-operator,C#,Operators,Null Coalescing Operator,我读到这篇关于操作符重载的文章 在该示例中,使用的运算符是+,-,还可以定义其他的*或/ 我想重载??运算符以用于字符串,如 string emptyString = emptyString ?? "OtherValue"; 而不是 string emptyString = string.IsNullOrEmpty(emptyString) ? "OtherValue" : emptyString; 我不想将字符串转换为对象并使用?进行比较 我知道??用于可空值类型,MSDN是这么说的: 这

我读到这篇关于操作符重载的文章

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

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

string emptyString = emptyString ?? "OtherValue";
而不是

string emptyString = string.IsNullOrEmpty(emptyString) ? "OtherValue" : emptyString;
不想将字符串转换为对象并使用
进行比较

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

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

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


我想问您是否有可能在C#中重载此运算符。上面的例子是一个简单的情况,需要使用
??

否。请看这里。“不能重载这些运算符”部分。

否。请查看此处。“不能重载这些运算符”部分。

根据您的说明,不能重载??操作员。

根据您不能超载??接线员。

不,你不能

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

 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'
尽管注意,我发现为了使扩展方法出现在第一类编译时常量上,例如
,您需要将该扩展方法合并到
系统中;i、 e:

 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);
    }
然而,你可以看到-你必须使用铸造开始转换,真的是非常丑陋和可怕的,好吧,只是不要这样做。但是你可以。我不会的

我需要更多的免责声明吗

关于该明确演员阵容的一点注意事项

我的很大一部分人认为
stringresult=fs??傅应该可以工作,但不能。原因是由
??
执行的
null
检查仅位于左侧的参考上-它的类型不可知,可空值类型除外。反编译IL时,只需将引用加载到堆栈上,然后检查其计算结果是否为true或false,代码在该点分支到将值加载到堆栈上的两个后续操作之一(这就是调用
FakeString
操作符的地方)。对于可空值类型,这种行为不同-编译器知道这些,因此会相应地更改其行为。

不,您不能

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

 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'
尽管注意,我发现为了使扩展方法出现在第一类编译时常量上,例如
,您需要将该扩展方法合并到
系统中;i、 e:

 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);
    }
然而,你可以看到-你必须使用铸造开始转换,真的是非常丑陋和可怕的,好吧,只是不要这样做。但是你可以。我不会的

我需要更多的免责声明吗

关于该明确演员阵容的一点注意事项


我的很大一部分人认为
stringresult=fs??傅应该可以工作,但不能。原因是由
??
执行的
null
检查仅位于左侧的参考上-它的类型不可知,可空值类型除外。反编译IL时,只需将引用加载到堆栈上,然后检查其计算结果是否为true或false,代码在该点分支到将值加载到堆栈上的两个后续操作之一(这就是调用
FakeString
操作符的地方)。对于可空值类型,这种行为不同-编译器知道这些,因此会相应地更改其行为。

我还考虑了字符串的扩展。可能不是
返回字符串。IsNullOrEmpty(实例)?alt:字符串
应该是
返回字符串。IsNullOrEmpty(实例)?alt:实例是-哇!昨晚我很晚才起床听网球赛-greatI不认为在4小时睡眠时做一个SO答案也可以作为字符串的扩展。也许可以代替
return string.IsNullOrEmpty(实例)?alt:字符串
应该是
返回字符串。IsNullOrEmpty(实例)?alt:实例是-哇!昨晚我听网球时睡得很晚——在4小时睡眠的情况下做这么一个答案并不好