Question simple:
Si vous avez un string x
, pour l’initialiser, procédez de l’une des manières suivantes:
string x = String.Empty;
ou
string x = null;
Qu'en est-il du paramètre générique T?
J'ai essayé de faire:
void someMethod<T>(T y)
{
T x = new T();
...
}
Générer une erreur:
Impossible de créer une instance du type de variable 'T' car elle n'a pas la contrainte new ()
Vous avez deux options:
Vous pouvez contraindre T: vous faites cela en ajoutant: where T : new()
à votre méthode. Maintenant, vous pouvez uniquement utiliser la variable someMethod
avec un type doté d'un constructeur par défaut sans paramètre (voir Contraintes sur les paramètres de type ).
Ou vous utilisez default(T)
. Pour un type de référence, cela donnera null
. Mais par exemple, pour une valeur entière, ceci donnera 0
(voir Mot-clé default dans Code générique ).
Voici une application console de base qui montre la différence:
using System;
namespace Stackoverflow
{
class Program
{
public static T SomeNewMethod<T>()
where T : new()
{
return new T();
}
public static T SomeDefaultMethod<T>()
where T : new()
{
return default(T);
}
struct MyStruct { }
class MyClass { }
static void Main(string[] args)
{
RunWithNew();
RunWithDefault();
}
private static void RunWithDefault()
{
MyStruct s = SomeDefaultMethod<MyStruct>();
MyClass c = SomeDefaultMethod<MyClass>();
int i = SomeDefaultMethod<int>();
bool b = SomeDefaultMethod<bool>();
Console.WriteLine("Default");
Output(s, c, i, b);
}
private static void RunWithNew()
{
MyStruct s = SomeNewMethod<MyStruct>();
MyClass c = SomeNewMethod<MyClass>();
int i = SomeNewMethod<int>();
bool b = SomeNewMethod<bool>();
Console.WriteLine("New");
Output(s, c, i, b);
}
private static void Output(MyStruct s, MyClass c, int i, bool b)
{
Console.WriteLine("s: " + s);
Console.WriteLine("c: " + c);
Console.WriteLine("i: " + i);
Console.WriteLine("b: " + b);
}
}
}
Il produit la sortie suivante:
New
s: Stackoverflow.Program+MyStruct
c: Stackoverflow.Program+MyClass
i: 0
b: False
Default
s: Stackoverflow.Program+MyStruct
c:
i: 0
b: False
utilisez le mot clé default
.
T x = default(T);
Voir: Mot clé par défaut dans le code générique (Guide de programmation C #)
Étant donné une variable t d'un type paramétré T, l'instruction t = null n'est valide que si T est un type de référence et que t = 0 ne fonctionnera que pour types de valeur numérique mais pas pour les structures. La solution consiste à utiliser le mot-clé par défaut, qui renvoie null pour les types de référence et zéro pour les types de valeur numérique. Pour les structures, il retournera chaque membre de la structure initialisée à zéro ou à zéro selon qu'il s'agisse de types de valeur ou de référence.
Vous devez ajouter une contrainte new
pour le paramètre de type T
.
void someMethod<T>(T y) where T : new()
{
T x = new T();
...
}
Cela ne sera cependant valable que pour les types avec un constructeur par défaut.
La clause where
pour T
est une contrainte de type generic . Dans ce cas, tout type T
auquel cette méthode est appliquée doit avoir un constructeur public sans paramètre.
Si vous avez vraiment besoin d'une instance de T et non d'une valeur null par défaut pour les types de référence, utilisez:
Activator.CreateInstance()
Vous pouvez utiliser la construction default
pour la définir sur le type par défaut de Type.
Le mot-clé default vous permet d'indiquer au compilateur qu'au moment de la compilation, la valeur par défaut de cette variable doit être utilisée. Si l'argument de type fourni est une valeur numérique (par exemple, int, long, decimal), la valeur par défaut est zéro. Si l'argument de type fourni est un type de référence, la valeur par défaut est null. Si l'argument de type fourni est une structure, la valeur par défaut de la structure est déterminée en initialisant chaque zone de membre de la structure sur zéro pour les types numériques ou sur null pour les types de référence.
Utilisez quelque chose comme:
T data = default(T);
Pour plus de détails, lisez: Initialisation des variables génériques à leurs valeurs par défaut