106 votes

Le meilleur moyen de tester si un type générique est une chaîne? (c #)

J'ai une classe générique qui devraient permettre à tout type primitif ou autrement. Le seul problème avec ceci est à l'aide de default(T). Lorsque vous appelez par défaut sur une valeur de type ou une chaîne de caractères, il initialise une valeur raisonnable (comme une chaîne vide). Lorsque vous appelez default(T) sur un objet, elle renvoie null. Pour diverses raisons, nous devons nous assurer que, s'il n'est pas un type primitif, alors nous aurons une instance par défaut du type, pas null. Voici tentative 1:

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

Problème - chaîne n'est pas un type de valeur, mais il ne possède pas de constructeur sans paramètre. Donc, la solution actuelle est:

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

Mais cela se sent comme une bidouille. Est-il une plus belle façon de gérer la chaîne de cas?

183voto

Matt Hamilton Points 98268

Gardez à l'esprit que default (string) est null, pas string.Empty. Vous voudrez peut-être un cas spécial dans votre code:

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

14voto

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

Non testé, mais la première chose qui me vint à l'esprit.

4voto

jfs Points 13605

Vous pouvez utiliser le TypeCode énumération. Appelez le GetTypeCode méthode sur des classes qui implémentent l'IConvertible interface pour obtenir le code de type d'une instance de cette classe. IConvertible est mis en œuvre par Boolean, SByte, Byte, Int16, UInt16, Int32 UInt32, Int64, UInt64, Single, Double, Decimal, DateTime, Char et String, de sorte que vous pouvez vérifier pour les types primitifs à l'aide de ce. Plus d'infos sur "Générique Vérification de Type".

-6voto

Anil Points 1

La discussion pour String ne fonctionne pas ici.

Pour que cela fonctionne, je devais avoir le code suivant pour les génériques -

    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>();
            } 
        } 

    }
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X