Dans .NET, un type de valeur (C # struct
) ne peut pas avoir de constructeur sans paramètres. Selon cet article, cela est rendu obligatoire par la spécification CLI. Ce qui se passe, c'est que pour chaque type de valeur, un constructeur par défaut est créé (par le compilateur?) Qui initialise tous les membres à zéro (ou null
).
Pourquoi est-il interdit de définir un tel constructeur par défaut?
Une utilisation triviale est pour les nombres rationnels:
public struct Rational {
private long numerator;
private long denominator;
public Rational(long num, long denom)
{ /* Todo: Find GCD etc. */ }
public Rational(long num)
{
numerator = num;
denominator = 1;
}
public Rational() // This is not allowed
{
numerator = 0;
denominator = 1;
}
}
En utilisant la version actuelle de C #, un Rational par défaut est 0/0
ce qui n'est pas si cool.
PS : les paramètres par défaut aideront-ils à résoudre ce problème pour C # 4.0 ou le constructeur par défaut défini par CLR sera-t-il appelé?
Jon Skeet a répondu:
Pour utiliser votre exemple, que voudriez-vous qu'il se passe lorsque quelqu'un:
Rational[] fractions = new Rational[1000];
Doit-il parcourir 1000 fois votre constructeur?
Bien sûr, c'est pourquoi j'ai écrit le constructeur par défaut en premier lieu. Le CLR doit utiliser le constructeur de mise à zéro par défaut quand aucun constructeur par défaut explicite n'est défini; de cette façon, vous ne payez que ce que vous utilisez. Ensuite, si je veux un conteneur de 1000 Rational
s par défaut (et que je souhaite optimiser les 1000 constructions), j'utiliserai List<Rational>
plutôt qu'un tableau.
Cette raison, à mon avis, n'est pas assez forte pour empêcher la définition d'un constructeur par défaut.
Rational()
invoque le ctor sans paramètre plutôt que le Rational(long num=0, long denom=1)
.
new Rational()
, invoquera le constructeur s'il existe, mais s'il n'existe pas, new Rational()
sera équivalent à default(Rational)
. Dans tous les cas, nous vous encourageons à utiliser la syntaxe default(Rational)
lorsque vous voulez la "valeur zéro" de votre structure (qui est un "mauvais" nombre avec votre conception proposée de Rational
). La valeur par défaut pour un type de valeur T
est toujours default(T)
. N'invoquera donc new Rational[1000]
jamais les constructeurs struct.
denominator - 1
à l'intérieur de la structure, de sorte que la valeur par défaut devienne 0/1
Then if I want a container of 1000 non-default Rationals (and want to optimize away the 1000 constructions) I will use a List<Rational> rather than an array.
Pourquoi attendriez-vous qu'un tableau appelle un constructeur différent à une liste pour une structure?