By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
455,204 Members | 1,465 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 455,204 IT Pros & Developers. It's quick & easy.

Tertiary Operator Confusion ( a = b ? c : d)

P: n/a
I don't know if this is a compiler error or not. It all kind of makes sense
but you would think that the compiler would check the types of the possible
outcomes of the tertiary operator (c and d) against the type of the variable
being assigned (a). Instead it compares the types of c and d which may not
be compatible. Just seems silly.

int? i;
object o;

//this is ok:
if (i.HasValue)
o = i;
else
o = DBNull.Value;

//this fails to compile
//Error 1 Type of conditional expression cannot be determined because
//there is no implicit conversion between 'int?' and 'System.DBNull'

o = i.HasValue ? i : DBNull.Value;

//these also fail for the same reason

o = i == null ? DBNull.Value: i;
o = i.HasValue ? i : "ABC";

//but these works

o = i.HasValue ? (object)i : DBNull.Value;
o = i.HasValue ? (object)i : (object)DBNull.Value;
o = i.HasValue ? i : (object)DBNull.Value;

Jan 26 '07 #1
Share this Question
Share on Google+
10 Replies


P: n/a
One observation. It does seem that the compiler is enforcing the rule
that both alternatives must have the same type. This makes sense to me
when you consider that such tertiary expressions can be used in
complicated compound expressions where the ultimate target type is not
as obvious as it might be with a simple assignment statement.

==============
Clay Burch
Syncfusion, Inc.

Jan 26 '07 #2

P: n/a

"ClayB" <cl***@syncfusion.comwrote in message
news:11**********************@s48g2000cws.googlegr oups.com...
One observation. It does seem that the compiler is enforcing the rule
that both alternatives must have the same type. This makes sense to me
when you consider that such tertiary expressions can be used in
complicated compound expressions where the ultimate target type is not
as obvious as it might be with a simple assignment statement.
However all expressions in .NET have a common type, which is object.
Probably the current error should be replaced with a warning, with the
ternary expression resolved as the nearest common supertype which may be
object, or the union of object with some set of interfaces. The compiler
could then determine which interface is subsequently used and automatically
generate the cast.
>
==============
Clay Burch
Syncfusion, Inc.

Jan 26 '07 #3

P: n/a
On Jan 26, 2:07 pm, "Ben Voigt" <r...@nospam.nospamwrote:
One observation. It does seem that the compiler is enforcing the rule
that both alternatives must have the same type. This makes sense to me
when you consider that such tertiary expressions can be used in
complicated compound expressions where the ultimate target type is not
as obvious as it might be with a simple assignment statement.
However all expressions in .NET have a common type, which is object.
Probably the current error should be replaced with a warning, with the
ternary expression resolved as the nearest common supertype which may be
object, or the union of object with some set of interfaces. The compiler
could then determine which interface is subsequently used and automatically
generate the cast.
Here are the rules which are actually used. Personally, I think it's
fine as it is:

<quote>
The second and third operands of the ?: operator control the type of
the conditional expression. Let X and Y be the types of the second and
third operands. Then,

*If X and Y are the same type, then this is the type of the
conditional expression.
*Otherwise, if an implicit conversion (13.1) exists from X to Y,
but not from Y to X, then Y is the type of the conditional expression.
*Otherwise, if an implicit conversion (13.1) exists from Y to X,
but not from X to Y, then X is the type of the conditional expression.
*Otherwise, no expression type can be determined, and a
compile-time error occurs.
</quote>

Jon

Jan 26 '07 #4

P: n/a
C# specification 2.0, 24.2.3:
... The compiler could then determine which interface is subsequently used
and automatically generate the cast.
"However, a nullable type never satisfies an interface constraint, even if
the underlying type implements the particular interface"
"Ben Voigt" <rb*@nospam.nospamha scritto nel messaggio
news:u2**************@TK2MSFTNGP04.phx.gbl...
>
"ClayB" <cl***@syncfusion.comwrote in message
news:11**********************@s48g2000cws.googlegr oups.com...
>One observation. It does seem that the compiler is enforcing the rule
that both alternatives must have the same type. This makes sense to me
when you consider that such tertiary expressions can be used in
complicated compound expressions where the ultimate target type is not
as obvious as it might be with a simple assignment statement.

However all expressions in .NET have a common type, which is object.
Probably the current error should be replaced with a warning, with the
ternary expression resolved as the nearest common supertype which may be
object, or the union of object with some set of interfaces. The compiler
could then determine which interface is subsequently used and
automatically generate the cast.
>>
==============
Clay Burch
Syncfusion, Inc.


Jan 26 '07 #5

P: n/a
"Andrew Robinson" <ne****@nospam.nospamschrieb im Newsbeitrag
news:uo**************@TK2MSFTNGP03.phx.gbl...
>I don't know if this is a compiler error or not. It all kind of makes sense
but you would think that the compiler would check the types of the possible
outcomes of the tertiary operator (c and d) against the type of the
variable being assigned (a). Instead it compares the types of c and d which
may not be compatible. Just seems silly.

int? i;
object o;

//this is ok:
if (i.HasValue)
o = i;
else
o = DBNull.Value;

//this fails to compile
//Error 1 Type of conditional expression cannot be determined because
//there is no implicit conversion between 'int?' and 'System.DBNull'

o = i.HasValue ? i : DBNull.Value;

//these also fail for the same reason

o = i == null ? DBNull.Value: i;
o = i.HasValue ? i : "ABC";

//but these works

o = i.HasValue ? (object)i : DBNull.Value;
o = i.HasValue ? (object)i : (object)DBNull.Value;
o = i.HasValue ? i : (object)DBNull.Value;

BTW

you also could use the null coalescing operator:

o = i ?? (object)DBNull.Value

But still you have to cast to object.

Christof
Jan 26 '07 #6

P: n/a
Onather remark:

if you cast the i to object, the result will be a boxed nullable int, not a
boxed int.
Could be an important difference.

"Andrew Robinson" <ne****@nospam.nospamschrieb im Newsbeitrag
news:uo**************@TK2MSFTNGP03.phx.gbl...
>I don't know if this is a compiler error or not. It all kind of makes sense
but you would think that the compiler would check the types of the possible
outcomes of the tertiary operator (c and d) against the type of the
variable being assigned (a). Instead it compares the types of c and d which
may not be compatible. Just seems silly.

int? i;
object o;

//this is ok:
if (i.HasValue)
o = i;
else
o = DBNull.Value;

//this fails to compile
//Error 1 Type of conditional expression cannot be determined because
//there is no implicit conversion between 'int?' and 'System.DBNull'

o = i.HasValue ? i : DBNull.Value;

//these also fail for the same reason

o = i == null ? DBNull.Value: i;
o = i.HasValue ? i : "ABC";

//but these works

o = i.HasValue ? (object)i : DBNull.Value;
o = i.HasValue ? (object)i : (object)DBNull.Value;
o = i.HasValue ? i : (object)DBNull.Value;

Jan 26 '07 #7

P: n/a
Christof Nordiek wrote:
you also could use the null coalescing operator:

o = i ?? (object)DBNull.Value
Hmm, that's interesting... I've not seen that used before. Printed and
stuck on my note board :)

--
Dylan Parry
http://electricfreedom.org | http://webpageworkshop.co.uk

Programming, n: A pastime similar to banging one's head
against a wall, but with fewer opportunities for reward.
Jan 26 '07 #8

P: n/a
It's actually a ternary operator, not a tertiary operator. Ternary refers to
the number of arguments. Tertiary would imply a ranking (primary, secondary,
tertiary).

///ark
Jan 26 '07 #9

P: n/a
Mark Wilden <mw*****@communitymtm.comwrote:
It's actually a ternary operator, not a tertiary operator. Ternary refers to
the number of arguments. Tertiary would imply a ranking (primary, secondary,
tertiary).
It's *a* ternary operator, and it's better described as *the*
conditonal operator. It happens to be the only ternary operator at the
moment (IIRC) but it's not guaranteed to be an unambiguous description
forever :)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Jan 26 '07 #10

P: n/a
"Jon Skeet [C# MVP]" <sk***@pobox.comwrote in message
news:MP************************@msnews.microsoft.c om...
Mark Wilden <mw*****@communitymtm.comwrote:
>It's actually a ternary operator, not a tertiary operator. Ternary refers
to
the number of arguments. Tertiary would imply a ranking (primary,
secondary,
tertiary).

It's *a* ternary operator
Isn't that what I said? :)
>, and it's better described as *the* conditonal operator
Agreed.

///ark
Jan 29 '07 #11

This discussion thread is closed

Replies have been disabled for this discussion.