it-swarm-es.tech

¿Asignación de operador condicional con tipos Nulalable <value>?

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

A menudo me encuentro con ganas de 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 NULL). Desafortunadamente, el compilador siente que "No hay una conversión implícita entre 'nulo' e 'int'", aunque ambos tipos serían válidos en una operación de asignación a un int anulable por sí mismos.

El operador de fusión nulo no es una opción, por lo que puedo ver, debido a la conversión en línea que debe ocurrir en la cadena .Text si no es nula.

Hasta donde sé, la única forma de hacer esto es usar una declaración 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 sabe una solución más elegante?

57
Grank

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

Si realmente desea usarlo de esta manera, debe convertir uno de los valores a Nullable <Int32> 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),
65
Alex Lyman

Creo que un método de utilidad podría ayudar a hacer esto más limpio.

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

luego

EmployeeNumber = Convert.To<int>(employeeNumberTextBox.Text, Int32.Parse);
8
NerdFury

Si bien Alex proporciona la respuesta correcta y próxima a su pregunta, prefiero usar TryParse:

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

Es más seguro y se ocupa de 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
user13493

Puede emitir la salida de Convertir:

EmployeeNumber = string.IsNullOrEmpty(employeeNumberTextBox.Text)
   ? null
   : (int?)Convert.ToInt32(employeeNumberTextBox.Text)
3
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;

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

1
Sandeep