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.
Related
This question already has answers here:
Why does >= return false when == returns true for null values?
(8 answers)
How to compare nullable types?
(8 answers)
nullable bool in if() statement - checks required?
(5 answers)
Closed 2 years ago.
Can someone explain to me why this works?
List<int> foo = null;
bool bar = foo?.Count > 7;
When foo is null, it becomes equivalent to the following:
bool bar = null > 7;
The IntelliSense is saying both null and 7 are of type Nullable<int>, but how did the compiler decide that?!
Additionally, Nullable<T> doesn't define a greater than operator. How could it? There is no guarantee that T defines a greater than operator.
As Rofus and Jeroin correctly pointed out in comments the conversion between T to T? is always implicit when you do the comparison with "Null" 7 becomes a "Nullable<int>"
bool bar = foo?.Count > 7;
is similar to -
int? count = null;
int? k = 7; // Implicit conversion here!
var bar = count > k;
For your second question on the > operator. Yes, while the Nullable<T> struct does not define operators such as <, >, or even ==, still the following code compiles and executes correctly which is similar to your case -
int? x = 3;
int? y = 10;
bool b = x > y;
This is because compiler lifts the greater than operator from underlying value type like -
bool b = (x.HasValue && y.HasValue) ? (x.Value > y.Value) : false;
Operator Lifting or Lifted Operators means you can implicitly use T's operators on T?. Compiler has different set of rules on different set of operators on handling them on Nullable<T> types.
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?
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.
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);
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;