This question already has answers here:
Nullable type issue with ?: Conditional Operator
(5 answers)
Closed 5 years ago.
I can sometimes assign null to int? but not inside a ? : , why?
example
int? a; // good
int? b; // good
a = null; // why is this allowed?
b = (a != null) ? 1 : null /* and this not allowed? */;
b = (a != null) ? 1 : (int?)null /* this is a fix */;
From the documentation:
Either the type of first_expression and second_expression must be the same, or an implicit conversion must exist from one type to the
other.
So, in b = (a != null) ? 1 : null type of first argument is int, and second argument is null, which violates the above rule.
In the second case, int can be implicitly converted to (int?)null, that's why it works.
Related
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.
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.
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 8 years ago.
I have this property:
int? firstClientID;
Why does this
firstClientID = dataRow.IsFirstClientIDNull()
? null
: (int.TryParse(dataRow.FirstClientID, out tempInt)
? tempInt
: 0);
not compile because
type of conditional statement cannot be determined since there is no
implicit conversion between null and int
and does
if (dataRow.IsFirstClientIDNull())
firstClientID = null;
else if (int.TryParse(dataRow.FirstClientID, out tempInt))
firstClientID = tempInt;
else
firstClientID = 0;
work? They seem to do the same thing.
From MSDN
Either the type of first_expression and second_expression must be the same, or an implicit conversion must exist from one type to the other.
i.e. You will need to ensure both legs of the conditional operator return the same type (i.e. cast through Nullable<int>).
firstClientID = dataRow.IsFirstClientIDNull()
? (int?)null
: (int.TryParse(dataRow.FirstClientID, out tempInt)
? tempInt
: 0);
(The conditional operator is not really the same as an if / then else branch, as the conditional operator must return data of the same type, whereas if can do anything in each leg of the branches, with no constraints on type compatability)
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);
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;