不,你不能。
一个简单的解决方法是使用扩展方法:
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
运算符然后被调用)。对于可为空的值类型,这种行为是不同的——编译器知道这些,因此会相应地改变它的行为。