Como posso retornar NULL de um método genérico em c #?

Eu tenho um método genérico com este código (simulado) (sim, estou ciente IList tem predicados, mas meu código não está usando IList mas alguma outra coleção, de qualquer forma isso é irrelevante para a questão …)

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. } 

Isso me dá um erro de compilation

“Não é possível converter nulo para o tipo de parâmetro ‘T’ porque pode ser um tipo de valor. Considere usar ‘default (T)’ em seu lugar.”

Posso evitar esse erro?

Duas opções:

  • Retorna o default(T) que significa que você retornará null se T for um tipo de referência (ou um tipo de valor anulável), 0 para int, ‘\ 0’ para char etc
  • Restringir T para ser um tipo de referência com a restrição where T : class e, em seguida, retornar null como normal
 return default(T); 

Você pode apenas ajustar suas restrições:

 where T : class 

Em seguida, retornando null é permitido.

Adicione a restrição de class como a primeira restrição ao seu tipo genérico.

 static T FindThing(IList collection, int id) where T : class, IThing, new() 
  1. Se você tem object, então precisa de typecast

     return (T)(object)(employee); 
  2. se você precisar retornar null.

     return default(T); 

Sua outra opção seria adicionar isso ao final da sua declaração:

  where T : class where T: IList 

Dessa forma, permitirá que você retorne null.

solução de TheSoftwareJedi funciona,

você também pode arquivá-lo usando alguns tipos de valor e anuláveis:

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

Abaixo estão as duas opções que você pode usar

 return default(T); 

ou

 where T : class, IThing return null; 

Tome a recomendação do erro … e o default(T) usuário default(T) ou o new T

Você precisará adicionar uma comparação em seu código para garantir que seja uma correspondência válida se você seguir essa rota.

Caso contrário, considere potencialmente um parâmetro de saída para “correspondência encontrada”.

Aqui está um exemplo de trabalho para valores de retorno do Nullable Enum:

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

Outra alternativa para as 2 respostas apresentadas acima. Se você alterar seu tipo de retorno para object , poderá retornar null , enquanto ao mesmo tempo, converter o retorno não nulo.

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