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#中重载此运算符.以上示例是需要使用时的简单情况??.
不,你不能.
一个简单的解决方法是使用扩展方法:
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运算符的位置)然后被召唤).对于可以为空的值类型,此行为是不同的 - 编译器知道这些行为,因此相应地更改其行为.