문제

I read this MSDN document regarding the operator overloading.

In that example, the operators used were +, - and also can define others * or /.

I want to overload ?? operator to be used for strings like

string emptyString = emptyString ?? "OtherValue";

instead of

string emptyString = string.IsNullOrEmpty(emptyString) ? "OtherValue" : emptyString;

I don't want to convert string to object and compare using ??.

I know that ?? is used for nullable value types, what MSDN says:

The ?? operator is called the null-coalescing operator and is used to define a default value for nullable value types or reference types.

It returns the left-hand operand if the operand is not null; otherwise it returns the right operand.

I want to ask you if is possible to overload this operator in C#. The above example is a simple situation when need to use ??.

도움이 되었습니까?

해결책

No. Please take a look here Overloadable Operators C# . Section 'These operators cannot be overloaded.'

다른 팁

No you can't.

A simple workaround would be to use an extension method:

 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'

Although note that I've found that in order for the extension method to appear on first-class compile-time constants such as "" you need to merge that extension method into System; i.e:

 namespace System {
   public static class MyStringExtensions { 
     // method here
   }
 }

Don't do this - but just for kicks

You could - although I wouldn't recommend it - write a wrapper type for String which contains implicit cast operators to and from string which return null if the string is empty - thus using the ?? operator on instances of that type would yield the correct behaviour:

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

However, has you can see - you have to use casting to kick off the conversion and really it's pretty ugly and horrible and, well, just don't do it. But you could. I wouldn't.

Do I need any more disclaimers?

A little note on that explicit cast

A big part of me thought that string result = fs ?? foo; should work but it does not. The reason being that the null check performed by ?? is on the reference on the left-hand side only - it's type agnostic except in the case of a nullable value type. Decompiling the IL, the reference is simply loaded onto the stack and then checked to see if it evaluates to true or false, the code branches at that point into one of two further operations that load a value onto the stack (which is where the FakeString operator then gets called). This behaviour is not the same for a nullable value type - the compiler has knowledge of those, and so changes its behaviour accordingly.

Acc to this you cannot overload ?? operator.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top