Tenho uma classe genérica que deve permitir qualquer tipo, primitivo ou não. O único problema com isso é usar default(T)
. Quando você chama default em um tipo de valor ou string, ele o inicializa com um valor razoável (como string vazia). Quando você chama default(T)
um objeto, ele retorna nulo. Por vários motivos, precisamos garantir que, se não for um tipo primitivo, teremos uma instância padrão do tipo, não nula. Aqui está a tentativa 1:
T createDefault()
{
if(typeof(T).IsValueType)
{
return default(T);
}
else
{
return Activator.CreateInstance<T>();
}
}
Problema - string não é um tipo de valor, mas não tem um construtor sem parâmetros. Portanto, a solução atual é:
T createDefault()
{
if(typeof(T).IsValueType || typeof(T).FullName == "System.String")
{
return default(T);
}
else
{
return Activator.CreateInstance<T>();
}
}
Mas isso parece um desastre. Existe uma maneira mais agradável de lidar com o caso da string?
is
palavra - chave? Isso não é útil aqui?Não testado, mas a primeira coisa que me veio à mente.
fonte
Você pode usar a enumeração TypeCode . Chame o método GetTypeCode em classes que implementam a interface IConvertible para obter o código de tipo para uma instância dessa classe. IConvertible é implementado por Boolean, SByte, Byte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Decimal, DateTime, Char e String, então você pode verificar por tipos primitivos usando isso. Mais informações sobre " Verificação de tipo genérico ".
fonte
Pessoalmente, gosto de sobrecarga de método:
fonte
Eu sei que esta pergunta é antiga, mas houve uma atualização.
Desde C # 7.0, você pode usar o
is
operador para comparar tipos. Você não precisa mais detypeof
como na resposta aceita.https://docs.microsoft.com/en-US/dotnet/csharp/language-reference/keywords/is
fonte
A discussão sobre String não está funcionando aqui.
Eu precisava seguir o código de genéricos para fazê-lo funcionar -
fonte
String
por nome, especialmente sem considerar um namespace, é ruim. E também não gosto da maneira como você se converte.