¿Asignación de operador condicional con tipos Nullables?


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

A menudo me encuentro queriendo hacer cosas como esta (EmployeeNumber es un Nullable<int> ya que es una propiedad en un objeto dbml LINQ-to-SQL donde la columna permite valores NULOS). Desafortunadamente, el compilador siente que "No hay conversión implícita entre 'null' e 'int'", a pesar de que ambos tipos serían válidos en una operación de asignación a un int nullable por su cuenta.

El operador coalescente nulo no es una opción por lo que puedo ver debido a la conversión en línea que debe ocurrir en el .Cadena de texto si no es null.

Por lo que sé, la única manera de hacer esto es usar una sentencia if y/o asignarla en dos pasos. En este caso particular me parece muy frustrante porque quería usar la sintaxis del inicializador de objetos y esta asignación estaría en el bloque de inicialización...

¿Alguien conoce una solución más elegante?

Author: CodesInChaos, 2008-09-16

5 answers

El problema se produce porque el operador condicional no observa cómo se usa el valor (asignado en este caso) para determinar el tipo de expresión just solo los valores verdadero/falso. En este caso, tiene un nully un Int32, y el tipo no se puede determinar (hay razones reales por las que no puede asumir Nullable).

Si realmente desea usarlo de esta manera, debe convertir uno de los valores a Nullable usted mismo, para que C # pueda resolver el tipo:

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

O

EmployeeNumber =
    string.IsNullOrEmpty(employeeNumberTextBox.Text)
    ? null
    : (int?)Convert.ToInt32(employeeNumberTextBox.Text),
 63
Author: Alex Lyman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-16 19:08:05

Creo que un método de utilidad podría ayudar a hacer este limpiador.

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);
    }
}

Entonces

EmployeeNumber = Convert.To<int>(employeeNumberTextBox.Text, Int32.Parse);
 8
Author: NerdFury,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-16 19:20:49

Mientras Alex proporciona la respuesta correcta y próxima a tu pregunta, yo prefiero usar TryParse:

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

Es más seguro y se encarga de los casos de entrada no válida, así como de su escenario de cadena vacía. De lo contrario, si el usuario ingresa algo como 1b, se le presentará una página de error con la excepción no controlada causada en Convert.ToInt32(string).

 6
Author: user13493,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-21 10:29:14

Puede emitir la salida de Convert:

EmployeeNumber = string.IsNullOrEmpty(employeeNumberTextBox.Text)
   ? null
   : (int?)Convert.ToInt32(employeeNumberTextBox.Text)
 3
Author: Abe Heidebrecht,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-16 19:05:30
//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;

EDITAR: Breve explicación de lo anterior, estaba tratando de obtener el valor de Posid (si su nonnull int y tener un valor mayor que 0) en varibale X1. Tuve que usar (int?) en Posid.Value para que el operador condicional no arrojara ningún error de compilación. Solo un FYI GetHolidayCount es un método WCF que podría dar null o cualquier número. Esperanza que ayuda

 1
Author: Sandeep,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-21 10:44:41