Reputation: 2767
Consider the following method:
public object Foo(bool flag)
{
if (flag)
return (new object(), new object());
return (null, new object()); //Compiler error over here!!
}
This does not compile showing the error I mentioned in the title of this question. I can fix that with just a cast like the following:
public object Foo(bool flag)
{
if (flag)
return (new object(), new object());
return ((object)null, new object());
}
So far so good. The weird part and the reason for which I am asking this is that if I change the syntax and I use ternary operator instead of if-else statement like this:
public object Boo(bool flag) => flag
? (new object(), new object())
: (null, new object());
Then no cast is needed!!! Why? IMHO both ways of writing the method are semantically equal. I know that the IL generated may not be the same (haven't checked that).
Upvotes: 1
Views: 3640
Reputation: 134811
The problem is that the null
expression has no definite type, it depends on the context in which it is used. In the case of the conditional operator, the compiler has to find a common type between (object, object)
and (null, object)
. In that case it can deduce that null
may be object
.
When the compiler sees (null, object)
and needs to convert to object
, the value null
can be a multitude of types thus the error. It's the same reason why it cannot infer a type for lambdas unless you give it a hint.
Action x = () => { }; // ok
var y = () => { }; // error
As an aside, rather than using (object)null
as the value, I would strongly suggest using default(object)
instead that way you're not tying yourself to a specific value, but rather a value appropriate for the type you give.
Upvotes: 7