是否可以为 C# 中的类重载空合并运算符?
例如,如果实例为空,我想返回一个默认值,如果不是,则返回该实例。代码看起来像这样:
   return instance ?? new MyClass("Default");  
但是,如果我想使用 null-coalescing 运算符来检查 MyClass.MyValue 是否已设置,该怎么办?
是否可以为 C# 中的类重载空合并运算符?
例如,如果实例为空,我想返回一个默认值,如果不是,则返回该实例。代码看起来像这样:
   return instance ?? new MyClass("Default");  
但是,如果我想使用 null-coalescing 运算符来检查 MyClass.MyValue 是否已设置,该怎么办?
好问题!它没有在可重载和不可重载运算符列表中以一种或另一种方式列出,并且在运算符页面上没有提及任何内容。
所以我尝试了以下方法:
public class TestClass
{
    public static TestClass operator ??(TestClass  test1, TestClass test2)
    {
        return test1;
    }
}
我收到错误“预期可重载的二进制运算符”。所以我想说,从 .NET 3.5 开始,答案是否定的。
简单的回答:没有
C# 设计原则不允许改变语言语义的运算符重载。因此复合赋值、三元运算符和...等复杂运算符不能重载。
据传这将成为下一版本 C# 的一部分。来自http://damieng.com/blog/2013/12/09/probable-c-6-0-features-illustrated
7. Monadic null 检查
无需在访问属性或方法之前检查空值。在 Groovy 中称为安全导航运算符)。
前
if (points != null) {
    var next = points.FirstOrDefault();
    if (next != null && next.X != null) return next.X;
}   
return -1;
后
var bestValue = points?.FirstOrDefault()?.X ?? -1;
我试图用我写的一个非常相似的结构来完成这个Nullable<T>。有了Nullable<T>你可以做类似的事情
Nullable<Guid> id1 = null;
Guid id2 = id1 ?? Guid.NewGuid();
尽管只定义了到 type的转换id1,但隐式转换fromNullable<Guid>到 a没有问题。用我自己的类型做同样的事情,它给出了一个错误GuidNullable<T>explicitT
操作员 '??' 不能应用于“MyType”和“Guid”类型的操作数
所以我认为编译器内置了一些魔法来为Nullable<T>. 所以作为替代...
我们不能覆盖??操作符,但是如果您希望合并操作符评估基础值而不是类(或在我的情况下为结构)本身,您可以只使用一种方法,从而需要很少的额外击键。在我上面的案例中,它看起来像这样:
public struct MyType<T>
{
    private bool _hasValue;
    internal T _value;
    public MyType(T value)
    {
        this._value = value;
        this._hasValue = true;
    }
    public T Or(T altValue)
    {
        if (this._hasValue)
            return this._value;
        else
            return altValue;
    }
}
用法:
MyType<Guid> id1 = null;
Guid id2 = id1.Or(Guid.Empty);
这很好用,因为它是一个结构,并且id1它本身实际上不能为空。对于一个类,扩展方法可以处理实例是否为空,只要您尝试检查的值是公开的:
public class MyClass
{
    public MyClass(string myValue)
    {
        MyValue = myValue;
    }
    public string MyValue { get; set; }
}
public static class MyClassExtensions
{ 
    public static string Or(this MyClass myClass, string altVal)
    {
        if (myClass != null && myClass.MyValue != null)
            return myClass.MyValue;
        else
            return altVal;
    }
}
用法:
MyClass mc1 = new MyClass(null);
string requiredVal = mc1.Or("default"); //Instead of mc1 ?? "default";
如果有人在这里寻找解决方案,最接近的例子就是这样做
return instance.MyValue != null ? instance : new MyClass("Default");