Unable to assign null to int? when using ternary (?:) operator [duplicate] - c#

This question already has answers here:
Nullable types and the ternary operator: why is `? 10 : null` forbidden? [duplicate]
(9 answers)
Closed 3 years ago.
Can anyone help me understand why the following doesnt compile?
string intAsString = "123";
int? nullableInt = null;
nullableInt = !string.IsNullOrEmpty(intAsString)
? Convert.ToInt32(intAsString)
: null;
As it complains that:
Type of conditional expression cannot be determined because there is no implicit conversion between int and null
I expected that since int? can be assigned null, this statement should work fine. It's easy enough to work around, but I'd like to understand why my expectation was wrong.

You need to explicitly cast the Int32 you get from Convert.ToInt32:
string intAsString = "123";
int? nullableInt = null;
nullableInt = !string.IsNullOrEmpty(intAsString) ? (int?)(Convert.ToInt32(intAsString)) : null;

The compiler finds out you have "int", and "null" as your result type. It is not smart enough to find a type fitting both. Cast one or the other explicitly to int?

Related

C# : why explicit conversion from Int to <Nullable> int? [duplicate]

This question already has answers here:
Nullable types and the ternary operator: why is `? 10 : null` forbidden? [duplicate]
(9 answers)
Closed 5 years ago.
int a = 1;
int? b = a;
Console.WriteLine(b);
The above snippet is fine and will convert int directly to int?, no explicit conversion is required
but
List<int> temp = new List<int>{1};
int? valueVariable = temp!=null && temp.Count>0 ? temp[0] : null ;
Console.WriteLine(valueVariable);
will have compile time error.
to fix this We need to cast to int?
// Working Snippet with int? casting
int? valueVariable = temp!=null && temp.Count > 0 ? (int?) temp[0] : null ;
https://dotnetfiddle.net/0x7ckL
Why we needed casting here,although the same was working for first example?
The reason is that ternary operator must use the SAME type in both branches. So true and false return values must be either int? or int. Cannot use two different types.

Coalescing operator vs Ternary operator [duplicate]

This question already has answers here:
Conditional operator assignment with Nullable<value> types?
(6 answers)
Why doesn't this C# code compile?
(4 answers)
Closed 9 years ago.
I just came across a weird error:
private bool GetBoolValue()
{
//Do some logic and return true or false
}
Then, in another method, something like this:
int? x = GetBoolValue() ? 10 : null;
Simple, if the method returns true, assign 10 to the Nullableint x. Otherwise, assign null to the nullable int. However, the compiler complains:
Error 1 Type of conditional expression cannot be determined because there is no implicit conversion between int and <null>.
Am I going nuts?
The compiler first tries to evaluate the right-hand expression:
GetBoolValue() ? 10 : null
The 10 is an int literal (not int?) and null is, well, null. There's no implicit conversion between those two hence the error message.
If you change the right-hand expression to one of the following then it compiles because there is an implicit conversion between int? and null (#1) and between int and int? (#2, #3).
GetBoolValue() ? (int?)10 : null // #1
GetBoolValue() ? 10 : (int?)null // #2
GetBoolValue() ? 10 : default(int?) // #3
Try this:
int? x = GetBoolValue() ? 10 : (int?)null;
Basically what is happening is that conditional operator is unable to determine the "return type" of the expression. Since the compiler implictitly decides that 10 is an int it then decides that the return type of this expression shall be an int as well. Since an int cannot be null (the third operand of the conditional operator) it complains.
By casting the null to a Nullable<int> we are telling the compiler explicitly that the return type of this expression shall be a Nullable<int>. You could have just as easily casted the 10 to int? as well and had the same effect.
Try this:
int? result = condition ? 10 : default(int?);
Incidentally, the Microsoft implementation of the C# compiler actually gets the type analysis of the conditional operator wrong in a very subtle and interesting (to me) way. My article on it is Type inference woes, part one (2006-05-24).
Try one of these:
int? x = GetBoolValue() ? (int?)10 : null;
int? x = GetBoolValue() ? 10 : (int?)null;
The problem is that the ternary operator is inferring type based on your first parameter assignment...10 in this case, which is an int, not a nullable int.
You might have better luck with:
int? x = GetBoolValue() (int?)10 : null;
int? x = GetBoolValue() ? 10 : (int?)null;
The reason you see this is because behind the scenes you're using Nullable and you need to tell C# that your "null" is a null instance of Nullable.
Just add an explict cast.
int? x = GetBoolValue() ? 10 : (int?)null;
It is the ternary operator that gets confused - the second argument is an integer and so is the third argument exspected to be an integer, too, and null does not fit.
It's because the compiler determines the type of the conditional operator by its second and third operand, not by what you assign the result to. There is no direct cast between an integer and an null reference that the compiler can use to determine the type.

Why can't I set a nullable int to null in a ternary if statement? [duplicate]

This question already has answers here:
Conditional operator cannot cast implicitly?
(3 answers)
Closed 9 years ago.
The C# code below:
int? i;
i = (true ? null : 0);
gives me the error:
Type of conditional expression cannot
be determined because there is no
implicit conversion between '<null>'
and 'int'
Shouldn't this be valid? What am i missing here?
The compiler tries to evaluate the right-hand expression. null is null and the 0 is an int literal, not int?. The compiler is trying to tell you that it can't determine what type the expression should evaluate as. There's no implicit conversion between null and int, hence the error message.
You need to tell the compiler that the expression should evaluate as an int?. There is an implicit conversion between int? and int, or between null and int?, so either of these should work:
int? x = true ? (int?)null : 0;
int? y = true ? null : (int?)0;
You need to use the default() keyword rather than null when dealing with ternary operators.
Example:
int? i = (true ? default(int?) : 0);
Alternately, you could just cast the null:
int? i = (true ? (int?)null : 0);
Personally I stick with the default() notation, it's just a preference, really. But you should ultimately stick to just one specific notation, IMHO.
HTH!
The portion (true ? null : 0) becomes a function in a way. This function needs a return type. When the compiler needs to figure out the return type it can't.
This works:
int? i;
i = (true ? null : (int?)0);

C# code won't compile. No implicit conversion between null and int [duplicate]

This question already has answers here:
Closed 13 years ago.
Possible Duplicate:
Nullable types and the ternary operator: why is `? 10 : null` forbidden?
Why doesn't this work? Seems like valid code.
string cert = ddCovCert.SelectedValue;
int? x = (string.IsNullOrEmpty(cert)) ? null: int.Parse(cert);
Display(x);
How should I code this? The method takes a Nullable. If the drop down has a string selected I need to parse that into an int otherwise I want to pass null to the method.
int? x = string.IsNullOrEmpty(cert) ? (int?)null : int.Parse(cert);
I've come across the same thing ... I usually just cast the null to (int?)
int? x = (string.IsNullOrEmpty(cert)) ? (int?)null: int.Parse(cert);

c# why can't a nullable int be assigned null as a value [duplicate]

This question already has answers here:
Conditional operator assignment with Nullable<value> types?
(6 answers)
Nullable types and the ternary operator: why is `? 10 : null` forbidden? [duplicate]
(9 answers)
Closed 9 years ago.
Explain why a nullable int can't be assigned the value of null e.g
int? accom = (accomStr == "noval" ? null : Convert.ToInt32(accomStr));
What's wrong with that code?
The problem isn't that null cannot be assigned to an int?. The problem is that both values returned by the ternary operator must be the same type, or one must be implicitly convertible to the other. In this case, null cannot be implicitly converted to int nor vice-versus, so an explict cast is necessary. Try this instead:
int? accom = (accomStr == "noval" ? (int?)null : Convert.ToInt32(accomStr));
What Harry S says is exactly right, but
int? accom = (accomStr == "noval" ? null : (int?)Convert.ToInt32(accomStr));
would also do the trick. (We Resharper users can always spot each other in crowds...)
Another option is to use
int? accom = (accomStr == "noval" ? Convert.DBNull : Convert.ToInt32(accomStr);
I like this one most.
Similarly I did for long:
myLongVariable = (!string.IsNullOrEmpty(cbLong.SelectedItem.Value)) ? Convert.ToInt64(cbLong.SelectedItem.Value) : (long?)null;

Categories

Resources