I discovered a strange behaviour of my program and after futher analysis, I was able to find that there is probably something wrong either in my C# knowledge or somewhere else. I beleive it's my mistake but I cannot find an answer anywhere...
public class B
{
public static implicit operator B(A values)
{
return null;
}
}
public class A { }
public class Program
{
static void Main(string[] args)
{
A a = new A();
B b = a ?? new B();
//b = null ... is it wrong that I expect b to be B() ?
}
}
The variable "b" in this code is evaluated to null. I don't get why is it null.
I googled and found a response in this question - Implicit casting of Null-Coalescing operator result - with the official specification.
But following this specification, I can't find the reason why "b" is null :( Maybe I'm reading it wrong in which case I apologize for spamming.
If A exists and is not a nullable type or a reference type, a compile-time error occurs.
...that's not the case.
If b is a dynamic expression, the result type is dynamic. At run-time, a is first evaluated. If a is not null, a is converted to dynamic, and this becomes the result. Otherwise, b is evaluated, and this becomes the result.
...that's also not the case.
Otherwise, if A exists and is a nullable type and an implicit conversion exists from b to A0, the result type is A0. At run-time, a is first evaluated. If a is not null, a is unwrapped to type A0, and this becomes the result. Otherwise, b is evaluated and converted to type A0, and this becomes the result.
...A exists, implicit conversion from b to A0 does not exist.
Otherwise, if A exists and an implicit conversion exists from b to A, the result type is A. At run-time, a is first evaluated. If a is not null, a becomes the result. Otherwise, b is evaluated and converted to type A, and this becomes the result.
...A exists, implicit conversion from b to A does not exist.
Otherwise, if b has a type B and an implicit conversion exists from a to B, the result type is B. At run-time, a is first evaluated. If a is not null, a is unwrapped to type A0 (if A exists and is nullable) and converted to type B, and this becomes the result. Otherwise, b is evaluated and becomes the result.
...b has a type B and implicit conversion exists from a to B. a is evaluated into null. Therefore, b should be evaluated and b should be the result.
Otherwise, a and b are incompatible, and a compile-time error occurs. Does not happen
Am I missing something please?
Why did you expect the null-coalescing operator to return new B()
? a
is not null, so a ?? new B()
evaluates to a
.
Now that we know that a
will be returned, we need to determine the type of the result (T
) and whether we need to cast a
to T
.
• Otherwise, if b has a type B and an implicit conversion exists from a to B, the result type is B. At run-time, a is first evaluated. If a is not null, a is unwrapped to type A0 (if A exists and is nullable) and converted to type B, and this becomes the result. Otherwise, b is evaluated and becomes the result.
An implicit conversion exists from A
to B
, so B
is the result type of the expression. Which means a
will be implicitly casted to B
. And your implicit operator returns null
.
In fact, if you write var b = a ?? new B();
(notice the var
), you'll see that the compiler infers B
to be the type returned by the expression.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With