W .NET typ wartości (C # struct
) nie może mieć konstruktora bez parametrów. Zgodnie z tym postem jest to wymagane przez specyfikację CLI. Co się dzieje, że dla każdego typu wartości tworzony jest domyślny konstruktor (przez kompilator?), Który inicjuje wszystkie elementy na zero (lub null
).
Dlaczego nie wolno definiować takiego domyślnego konstruktora?
Jednym trywialnym zastosowaniem są liczby wymierne:
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;
}
}
Używając bieżącej wersji C #, domyślnym produktem Rational jest to, 0/0
co nie jest tak fajne.
PS : Czy domyślne parametry pomogą rozwiązać ten problem w C # 4.0, czy też zostanie wywołany domyślny konstruktor zdefiniowany w CLR?
Jon Skeet odpowiedział:
Na przykład, co chciałbyś zrobić, gdy ktoś to zrobił:
Rational[] fractions = new Rational[1000];
Czy powinien przejść przez twój konstruktor 1000 razy?
Pewnie, że właśnie dlatego napisałem domyślnego konstruktora. CLR powinien używać domyślnego konstruktora zerowania, gdy nie zdefiniowano żadnego jawnego domyślnego konstruktora; w ten sposób płacisz tylko za to, czego używasz. Następnie, jeśli chcę kontener 1000 domyślnych Rational
(i chcę zoptymalizować 1000 konstrukcji), użyję List<Rational>
raczej tablicy niż tablicy.
Moim zdaniem ten powód nie jest wystarczająco silny, aby zapobiec definicji domyślnego konstruktora.
Rational()
wywołuje raczej parametryczny ctor niż Rational(long num=0, long denom=1)
.
new Rational()
wywoła konstruktor, jeśli istnieje, jednak jeśli nie istnieje, new Rational()
będzie równoważny default(Rational)
. W każdym razie zachęca się do użycia składni, default(Rational)
gdy chce się „zerowej wartości” struktury (która jest „złą” liczbą w proponowanym projekcie Rational
). Domyślną wartością dla typu wartości T
jest zawsze default(T)
. Dlatego new Rational[1000]
nigdy nie będzie wywoływał konstruktorów struktur.
denominator - 1
w strukturze, aby domyślna wartość
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.
Dlaczego miałbyś oczekiwać, że tablica wywoła inny konstruktor do listy dla struktury?