¿Cómo puedo devolver NULL desde un método genérico en C #?

Tengo un método genérico con este código (ficticio) (sí, soy consciente de que IList tiene predicados, pero mi código no usa IList, sino alguna otra colección; de todos modos, esto es irrelevante para la pregunta …)

static T FindThing(IList collection, int id) where T : IThing, new() { foreach T thing in collecion { if (thing.Id == id) return thing; } return null; // ERROR: Cannot convert null to type parameter 'T' because it could be a value type. Consider using 'default(T)' instead. } 

Esto me da un error de comstackción

“No se puede convertir nulo para escribir el parámetro ‘T’ porque podría ser un tipo de valor. Considere usar ‘predeterminado (T)’ en su lugar”.

¿Puedo evitar este error?

Dos opciones:

  • Return default(T) que significa que devolverá null si T es un tipo de referencia (o un tipo de valor que puede ser anulado), 0 para int, ‘\ 0’ para char, etc.
  • Restrinja T para que sea un tipo de referencia con la restricción where T : class y luego devuelva nulo como es normal
 return default(T); 

Usted puede simplemente ajustar sus restricciones:

 where T : class 

Luego, se permite devolver nulo.

Agregue la restricción de clase como la primera restricción a su tipo genérico.

 static T FindThing(IList collection, int id) where T : class, IThing, new() 
  1. Si tiene un objeto, entonces necesita encasillar

     return (T)(object)(employee); 
  2. si necesita devolver nulo.

     return default(T); 

Su otra opción sería agregar esto al final de su statement:

  where T : class where T: IList 

De esa forma, le permitirá regresar nulo.

solución de obras de TheSoftwareJedi,

también puedes archivarlo usando un par de valores y tipos que aceptan valores numéricos:

 static T? FindThing(IList collection, int id) where T : struct, IThing { foreach T thing in collecion { if (thing.Id == id) return thing; } return null; } 

A continuación están las dos opciones que puedes usar

 return default(T); 

o

 where T : class, IThing return null; 

Tome la recomendación del error … y ya sea el usuario por default(T) o el new T

Deberá agregar una comparación en su código para asegurarse de que sea una coincidencia válida si realiza esa ruta.

De lo contrario, considere potencialmente un parámetro de salida para “coincidencia encontrada”.

Aquí hay un ejemplo de trabajo para los valores de retorno Nullable Enum:

 public static TEnum? ParseOptional(this string value) where TEnum : struct { return value == null ? (TEnum?)null : (TEnum) Enum.Parse(typeof(TEnum), value); } 

Otra alternativa a 2 respuestas presentadas arriba. Si cambia su tipo de devolución a object , puede devolver null , mientras que al mismo tiempo emite el retorno no nulo.

 static object FindThing(IList collection, int id) { foreach T thing in collecion { if (thing.Id == id) return (T) thing; } return null; // allowed now }