In .NET kann ein Werttyp (C # struct
) keinen Konstruktor ohne Parameter haben. Laut diesem Beitrag ist dies in der CLI-Spezifikation vorgeschrieben. Was passiert ist, dass für jeden Werttyp ein Standardkonstruktor erstellt wird (vom Compiler?), Der alle Mitglieder auf Null (oder null
) initialisiert .
Warum ist es nicht erlaubt, einen solchen Standardkonstruktor zu definieren?
Eine triviale Verwendung sind rationale Zahlen:
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;
}
}
Bei Verwendung der aktuellen Version von C # ist ein Standard-Rational 0/0
nicht so cool.
PS : Helfen Standardparameter bei der Lösung dieses Problems für C # 4.0 oder wird der CLR-definierte Standardkonstruktor aufgerufen?
Jon Skeet antwortete:
Um Ihr Beispiel zu verwenden: Was möchten Sie tun, wenn jemand Folgendes tut:
Rational[] fractions = new Rational[1000];
Sollte es 1000 Mal durch Ihren Konstruktor laufen?
Sicher sollte es, deshalb habe ich zuerst den Standardkonstruktor geschrieben. Die CLR sollte den Standard-Nullungskonstruktor verwenden, wenn kein expliziter Standardkonstruktor definiert ist. Auf diese Weise zahlen Sie nur für das, was Sie verwenden. Wenn ich dann einen Container mit 1000 nicht standardmäßigen Rational
s möchte (und die 1000 Konstruktionen optimieren möchte), verwende ich List<Rational>
eher ein als ein Array.
Dieser Grund ist meiner Meinung nach nicht stark genug, um die Definition eines Standardkonstruktors zu verhindern.
Rational()
der parameterlose ctor anstelle des aufgerufen wird Rational(long num=0, long denom=1)
.
new Rational()
wird der Konstruktor aufrufen , wenn es vorhanden ist , aber wenn es nicht existiert new Rational()
wird äquivalent default(Rational)
. In jedem Fall werden Sie aufgefordert, die Syntax zu verwenden, default(Rational)
wenn Sie den "Nullwert" Ihrer Struktur wünschen (was eine "schlechte" Zahl bei Ihrem vorgeschlagenen Design von ist Rational
). Der Standardwert für einen Werttyp T
ist immer default(T)
. So new Rational[1000]
wird nie invoke struct Konstrukteure.
denominator - 1
in der Struktur speichern , sodass der Standardwert 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.
Warum sollte ein Array einen anderen Konstruktor für eine Liste für eine Struktur aufrufen?