Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conditional operator assignment with Nullable<value> types?

EmployeeNumber =
string.IsNullOrEmpty(employeeNumberTextBox.Text)
    ? null
    : Convert.ToInt32(employeeNumberTextBox.Text),

I often find myself wanting to do things like this (EmployeeNumber is a Nullable<int> as it's a property on a LINQ-to-SQL dbml object where the column allows NULL values). Unfortunately, the compiler feels that

There is no implicit conversion between 'null' and 'int'

even though both types would be valid in an assignment operation to a nullable int on their own.

Using the null coalescing operator is not an option as far as I can see because of the inline conversion that needs to happen on the .Text string if it's not null.

As far as I know the only way to do this is to use an if statement and/or assign it in two steps. In this particular case I find that very frustrating because I wanted to use the object initializer syntax and this assignment would be in the initialization block...

Does anyone know a more elegant solution?

like image 546
Grank Avatar asked Sep 16 '08 19:09

Grank


People also ask

What is null conditional operator in C#?

Null-conditional operators ?. and ?[] Available in C# 6 and later, a null-conditional operator applies a member access, ?. , or element access, ?[] , operation to its operand only if that operand evaluates to non-null; otherwise, it returns null . That is, If a evaluates to null , the result of a?. x or a?[x] is null .

What are nullable value types?

You typically use a nullable value type when you need to represent the undefined value of an underlying value type. For example, a Boolean, or bool , variable can only be either true or false . However, in some applications a variable value can be undefined or missing.

What is a conditional null?

The null conditional is a form of a member access operator (the .). Here's a simplified explanation for the null conditional operator: The expression A?. B evaluates to B if the left operand (A) is non-null; otherwise, it evaluates to null.

What is the use of HasValue in C#?

The HasValue property returns true if the variable contains a value, or false if it is null. You can only use == and != operators with a nullable type. For other comparison use the Nullable static class.


5 Answers

The problem occurs because the conditional operator doesn't look at how the value is used (assigned in this case) to determine the type of the expression -- just the true/false values. In this case, you have a null and an Int32, and the type can not be determined (there are real reasons it can't just assume Nullable<Int32>).

If you really want to use it in this way, you must cast one of the values to Nullable<Int32> yourself, so C# can resolve the type:

EmployeeNumber =
    string.IsNullOrEmpty(employeeNumberTextBox.Text)
    ? (int?)null
    : Convert.ToInt32(employeeNumberTextBox.Text),

or

EmployeeNumber =
    string.IsNullOrEmpty(employeeNumberTextBox.Text)
    ? null
    : (int?)Convert.ToInt32(employeeNumberTextBox.Text),
like image 67
Alex Lyman Avatar answered Oct 05 '22 01:10

Alex Lyman


I think a utility method could help make this cleaner.

public static class Convert
{
    public static T? To<T>(string value, Converter<string, T> converter) where T: struct
    {
        return string.IsNullOrEmpty(value) ? null : (T?)converter(value);
    }
}

then

EmployeeNumber = Convert.To<int>(employeeNumberTextBox.Text, Int32.Parse);
like image 34
NerdFury Avatar answered Oct 05 '22 00:10

NerdFury


While Alex provides the correct and proximal answer to your question, I prefer to use TryParse:

int value;
int? EmployeeNumber = int.TryParse(employeeNumberTextBox.Text, out value)
    ? (int?)value
    : null;

It's safer and takes care of cases of invalid input as well as your empty string scenario. Otherwise if the user inputs something like 1b they will be presented with an error page with the unhandled exception caused in Convert.ToInt32(string).

like image 25
user13493 Avatar answered Oct 04 '22 23:10

user13493


You can cast the output of Convert:

EmployeeNumber = string.IsNullOrEmpty(employeeNumberTextBox.Text)
   ? null
   : (int?)Convert.ToInt32(employeeNumberTextBox.Text)
like image 28
Abe Heidebrecht Avatar answered Oct 04 '22 23:10

Abe Heidebrecht


//Some operation to populate Posid.I am not interested in zero or null
int? Posid = SvcClient.GetHolidayCount(xDateFrom.Value.Date,xDateTo.Value.Date).Response;
var x1 = (Posid.HasValue && Posid.Value > 0) ? (int?)Posid.Value : null;

EDIT: Brief explanation of above, I was trying to get the value of Posid (if its nonnull int and having value greater than 0) in varibale X1. I had to use (int?) on Posid.Value to get the conditional operator not throwing any compilation error. Just a FYI GetHolidayCount is a WCF method that could give null or any number. Hope that helps

like image 32
Sandeep Avatar answered Oct 05 '22 01:10

Sandeep