Possible to overload null-coalescing operator?

后端 未结 6 1941
栀梦
栀梦 2020-12-17 07:54

Is it possible to overload the null-coalescing operator for a class in C#?

Say for example I want to return a default value if an instance is null and return the i

6条回答
  •  臣服心动
    2020-12-17 08:16

    I was trying to accomplish this with a struct I wrote that was very similar Nullable. With Nullable you can do something like

    Nullable id1 = null;
    Guid id2 = id1 ?? Guid.NewGuid();
    

    It has no problem implicitly converting id1 from Nullable to a Guid despite the fact that Nullable only defines an explicit conversion to type T. Doing the same thing with my own type, it gives an error

    Operator '??' cannot be applied to operands of type 'MyType' and 'Guid'

    So I think there's some magic built into the compiler to make a special exception for Nullable. So as an alternative...

    tl;dr

    We can't override the ?? operator, but if you want the coalesce operator to evaluate an underlying value rather than the class (or struct in my case) itself, you could just use a method resulting in very few extra keystrokes required. With my case above it looks something like this:

    public struct MyType
    {
        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;
        }
    }
    

    Usage:

    MyType id1 = null;
    Guid id2 = id1.Or(Guid.Empty);
    

    This works well since it's a struct and id1 itself can't actually be null. For a class, an extension method could handle if the instance is null as long as the value you're trying to check is exposed:

    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;
        }
    }
    

    Usage:

    MyClass mc1 = new MyClass(null);
    string requiredVal = mc1.Or("default"); //Instead of mc1 ?? "default";
    

提交回复
热议问题