Pergunta

Eu 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 uma string vazia).Quando Você ligar default(T) em 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 nulo.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 possui um construtor sem parâmetros.Então, 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 erro.Existe uma maneira melhor de lidar com o caso das strings?

Foi útil?

Solução

Tenha em mente que default(string) é nulo, não string.Empty.Você pode querer um caso especial em seu código:

if (typeof(T) == typeof(String)) return (T)(object)String.Empty;

Outras dicas

if (typeof(T).IsValueType || typeof(T) == typeof(String))
{
     return default(T);
}
else
{
     return Activator.CreateInstance<T>();
}

Não testado, mas a primeira coisa que me veio à mente.

Você pode usar o Código de tipo enumeração.Chame o método GetTypeCode em classes que implementam a interface IConvertible para obter o código de tipo de uma instância dessa classe.IConvertible é implementado por Boolean, SByte, Byte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Decimal, DateTime, Char e String, para que você possa verificar tipos primitivos usando isso.Mais informações em "Verificação de tipo genérico".

Pessoalmente, gosto de sobrecarga de métodos:

public static class Extensions { 
  public static String Blank(this String me) {      
    return String.Empty;
  }
  public static T Blank<T>(this T me) {      
    var tot = typeof(T);
    return tot.IsValueType
      ? default(T)
      : (T)Activator.CreateInstance(tot)
      ;
  }
}
class Program {
  static void Main(string[] args) {
    Object o = null;
    String s = null;
    int i = 6;
    Console.WriteLine(o.Blank()); //"System.Object"
    Console.WriteLine(s.Blank()); //""
    Console.WriteLine(i.Blank()); //"0"
    Console.ReadKey();
  }
}

A discussão sobre String não está funcionando aqui.

Eu precisava do seguinte código para genéricos para que funcionasse -

   private T createDefault()
    { 

        {     
            if(typeof(T).IsValueType)     
            {         
                return default(T);     
            }
            else if (typeof(T).Name == "String")
            {
                return (T)Convert.ChangeType(String.Empty,typeof(T));
            }
            else
            {
                return Activator.CreateInstance<T>();
            } 
        } 

    }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top