Eu tenho um método genérico com esse código (fictício) (sim, eu sei que IList tem predicados, mas meu código não está usando IList, mas alguma outra coleção, de qualquer maneira isso é irrelevante para a pergunta ...)
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.
}
Isso me dá um erro de compilação
"Não é possível converter nulo no parâmetro de tipo 'T' porque pode ser um tipo de valor. Considere usar 'padrão (T)'."
Posso evitar esse erro?
null
independentemente de seT
éObject
ouint
ouchar
.Respostas:
Duas opções:
default(T)
que significa que você retornaránull
se T for um tipo de referência (ou um tipo de valor anulável),0
forint
,'\0'
forchar
, etc. ( Tabela de valores padrão (Referência de C #) )where T : class
restrição e retornenull
normalmentefonte
Nullable<int>
ou emNullable<DateTime>
vez disso. Se você usa um tipo não nulo e precisa representar um valor nulo, está apenas pedindo problemas.fonte
Você pode apenas ajustar suas restrições:
Então, retornar nulo é permitido.
fonte
IDisposable
. Sim, na maioria das vezes não precisa ser.System.String
não implementaIDisposable
, por exemplo. O respondente deveria ter esclarecido isso, mas isso não faz a resposta errada. :)Adicione a restrição de classe como a primeira restrição ao seu tipo genérico.
fonte
Se você tiver um objeto, precisará digitar
se você precisar retornar nulo.
fonte
Abaixo estão as duas opções que você pode usar
ou
fonte
Sua outra opção seria adicionar isso ao final da sua declaração:
Dessa forma, você poderá retornar nulo.
fonte
where T : class, IList
. Se você tiver restrições para tipos diferentes, repita o tokenwhere
, como emwhere TFoo : class where TBar : IList
.solução de TheSoftwareJedi funciona,
Também é possível arquivá-lo usando alguns tipos de valor e valores nulos:
fonte
Siga a recomendação do erro ... e use user
default(T)
ounew T
.Você precisará adicionar uma comparação ao seu código para garantir que seja uma correspondência válida se você seguir esse caminho.
Caso contrário, considere potencialmente um parâmetro de saída para "correspondência encontrada".
fonte
Aqui está um exemplo de trabalho para valores de retorno Nullable Enum:
fonte
where TEnum : struct, Enum
. Isso garante que um chamador não forneça acidentalmente um tipo de valor que não seja um enum (como umint
ou aDateTime
).Outra alternativa para as 2 respostas apresentadas acima. Se você alterar o tipo de retorno para
object
, poderá retornar enull
, ao mesmo tempo, converter o retorno não nulo.fonte
Por uma questão de integridade, é bom saber que você também pode fazer isso:
Retorna o mesmo que
return default(T);
fonte
Para mim, funciona como está. Onde exatamente está o problema?
fonte