W generics C # możemy zadeklarować ograniczenie parametru typu T
do domyślnego konstruktora, mówiąc where T : new()
. Jednak żadne inne ograniczenia tego rodzaju nie są ważne - new(string)
na przykład itp.
Z jakich powodów projekt i / lub implementacja języka jest tego przyczyną?
Czy jest coś w sposobie działania konstruktorów lub w sposobie implementacji systemu typów, który zabrania tego (a przynajmniej utrudnia)? Jeśli tak, co to jest? Pamiętam czytanie gdzieś, że default(T)
faktycznie kompiluje się new T()
do T : struct
. Może to ma związek z tym?
Czy jest to po prostu decyzja projektowa podjęta w celu uniknięcia nadmiernego skomplikowania języka?
c#
language-design
generics
Theodoros Chatzigiannakis
źródło
źródło
new(string)
nie jest domyślnym ograniczeniem konstruktora. Twoje pytanie jest równoznaczne ze stwierdzeniem „Dlaczego nie istnieją ograniczenia wymagające konkretnych podpisów konstruktorów?” Bardzo prawdopodobne, ponieważ takie ograniczenie nie byłoby szczególnie przydatne.Odpowiedzi:
Aby uzyskać wiarygodną odpowiedź, odsyłam do odpowiedzi Erica Lipperta na to pytanie na StackOverflow kilka lat temu, której fragment przytoczono poniżej.
źródło
Dekompilacja (zgodnie z sugestią Roberta Harveya) dała następujące, dla wszystkich zainteresowanych. Ta metoda:
Najwyraźniej po skompilowaniu staje się to:
T
jest typem wartości,new()
staje siędefault(T)
.T
jest typem odniesienia,new()
działa przy użyciu odbicia.Activator.CreateInstance()
połączenia wewnętrzneRuntimeType.CreateInstanceDefaultCtor()
.Tak więc jest - wewnętrznie domyślne konstruktory są naprawdę specjalne dla C # w stosunku do CLR. Takie samo traktowanie innych konstruktorów byłoby kosztowne, nawet jeśli istnieją pewne uzasadnione przypadki użycia dla bardziej skomplikowanych ograniczeń w rodzajach.
źródło
default(T)
dla typów wartości?t
zmienna (którą można zastąpić zagnieżdżonymireturn
instrukcjami).