Tengo un método genérico con este código (ficticio) (sí, sé que IList tiene predicados, pero mi código no está usando IList sino alguna otra colección, de todos modos esto es irrelevante para la pregunta ...)
static T FindThing<T>(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 compilación
"No se puede convertir nulo al parámetro de tipo 'T' porque podría ser un tipo de valor. Considere usar 'default (T)' en su lugar".
¿Puedo evitar este error?
null
independientemente de siT
esObject
oint
ochar
.Respuestas:
Dos opciones:
default(T)
que significa que devolveránull
si T es un tipo de referencia (o un tipo de valor anulable),0
paraint
,'\0'
parachar
, etc. ( Tabla de valores predeterminados (Referencia de C #) )where T : class
restricción y luego regresenull
como normalfuente
Nullable<int>
, oNullable<DateTime>
en su lugar. Si usa un tipo no anulable y necesita representar un valor nulo, solo está buscando problemas.fuente
Simplemente puede ajustar sus restricciones:
Luego, devolver nulo está permitido.
fuente
IDisposable
. Sí, la mayoría de las veces no tiene que ser así.System.String
no implementaIDisposable
, por ejemplo. El respondedor debería haber aclarado eso, pero eso no hace que la respuesta sea incorrecta. :)Agregue la restricción de clase como la primera restricción a su tipo genérico.
fuente
Si tiene un objeto, entonces necesita escribir
si necesita devolver nulo.
fuente
A continuación se encuentran las dos opciones que puede usar
o
fuente
Su otra opción sería agregar esto al final de su declaración:
De esa manera te permitirá volver nulo.
fuente
where T : class, IList
. Si tiene restricciones para diferentes tipos, repita el tokenwhere
, como enwhere TFoo : class where TBar : IList
.solución de TheSoftwareJedi funciona,
También puede archivarlo usando un par de valores y tipos anulables:
fuente
Tome la recomendación del error ... y ya sea usuario
default(T)
onew T
.Tendrás que agregar una comparación en tu código para asegurarte de que sea una coincidencia válida si sigues esa ruta.
De lo contrario, considere potencialmente un parámetro de salida para "coincidencia encontrada".
fuente
Aquí hay un ejemplo de trabajo para los valores de retorno de Nullable Enum:
fuente
where TEnum : struct, Enum
. Esto garantiza que la persona que llama no proporcione accidentalmente un tipo de valor que no sea una enumeración (como unaint
o unaDateTime
).Otra alternativa a las 2 respuestas presentadas anteriormente. Si cambia su tipo de retorno a
object
, puede regresarnull
, al mismo tiempo que emite el retorno no nulo.fuente
Para completar, es bueno saber que también podrías hacer esto:
Devuelve lo mismo que
return default(T);
fuente
Para mí funciona como es. ¿Dónde está exactamente el problema?
fuente