Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Wyrażenia typu docelowego
Notatka
Ten artykuł jest specyfikacją funkcji. Specyfikacja służy jako dokument projektowy dla funkcji. Zawiera proponowane zmiany specyfikacji wraz z informacjami wymaganymi podczas projektowania i opracowywania funkcji. Te artykuły są publikowane do momentu sfinalizowania proponowanych zmian specyfikacji i włączenia ich do obecnej specyfikacji ECMA.
Mogą wystąpić pewne rozbieżności między specyfikacją funkcji a ukończoną implementacją. Te różnice są przechwytywane w odpowiednich spotkania projektowego języka (LDM).
Więcej informacji na temat procesu wdrażania specyfikacji funkcji można znaleźć w standardzie języka C# w artykule dotyczącym specyfikacji .
Problem dotyczący czempiona: https://github.com/dotnet/csharplang/issues/100
Streszczenie
Nie wymagaj specyfikacji typu dla konstruktorów, gdy typ jest znany.
Motywacja
Zezwalaj na inicjowanie pól bez duplikowania typu.
Dictionary<string, List<int>> field = new() {
{ "item1", new() { 1, 2, 3 } }
};
Zezwalaj na pominięcie typu, gdy można go wywnioskować z użycia.
XmlReader.Create(reader, new() { IgnoreWhitespace = true });
Utwórz wystąpienie obiektu bez określania typu.
private readonly static object s_syncObj = new();
Specyfikacja
Nowa forma składniowa target_typed_new dla object_creation_expression jest akceptowana, w której typ jest opcjonalny.
object_creation_expression
: 'new' type '(' argument_list? ')' object_or_collection_initializer?
| 'new' type object_or_collection_initializer
| target_typed_new
;
target_typed_new
: 'new' '(' argument_list? ')' object_or_collection_initializer?
;
Wyrażenie target_typed_new nie posiada typu. Istnieje jednak nowa konwersja tworzenia obiektów, która jest niejawną konwersją z wyrażenia, umożliwiająca przejście z target_typed_new na każdy typ.
Biorąc pod uwagę typ docelowy T, typ T0 jest typem bazowym dla T, jeśli T jest wystąpieniem System.Nullable. W przeciwnym razie T0 jest T. Znaczenie wyrażenia target_typed_new konwertowanego na typ T jest takie samo jak znaczenie odpowiadającego object_creation_expression określającego T0 jako typ.
Jest to błąd czasu kompilacji, jeśli target_typed_new jest używany jako operand jednoargumentowego lub binarnego operatora, lub jeśli jest używany, gdy nie podlega konwersji tworzenia obiektu.
otwarty problem: czy należy zezwolić delegatom i krotkom na typ docelowy?
Reguły powyżej obejmują delegaty (typ odwołania) i krotki (typ struktury). Chociaż oba typy można skonstruować, jeśli typ można wywnioskować, można już użyć funkcji anonimowej lub literału krotki.
(int a, int b) t = new(1, 2); // "new" is redundant
Action a = new(() => {}); // "new" is redundant
(int a, int b) t = new(); // OK; same as (0, 0)
Action a = new(); // no constructor found
Różne
Poniżej przedstawiono konsekwencje specyfikacji:
-
throw new()jest dozwolona (typ docelowy toSystem.Exception) - Typ docelowy
newnie jest dozwolony w przypadku operatorów binarnych. - Nie jest dozwolone, gdy nie ma typu docelowego: operatory jednoargumentowe, kolekcja
foreach, wusing, w dekonstrukcji, w wyrażeniuawait, jako właściwość typu anonimowego (new { Prop = new() }), w instrukcjilock, w instrukcjisizeof, w instrukcjifixed, w dostępie do członka (new().field), w operacji dynamicznie wysyłanej (someDynamic.Method(new())), w zapytaniu LINQ, jako operand operatorais, jako lewy operand operatora??, ... - Jest również niedozwolony jako
ref. - Następujące rodzaje typów nie są dozwolone jako obiekty docelowe konwersji
-
typy wyliczenia:
new()będzie działać (ponieważnew Enum()działa, aby nadać wartość domyślną), alenew(1)nie będzie działać, ponieważ typy wyliczenia nie mają konstruktora. - Typy interfejsów: To działałoby tak samo jak odpowiednie wyrażenie tworzenia dla typów COM.
- typy tablic: tablice wymagają specjalnej notacji, aby określić długość.
-
dynamiczna: nie zezwalamy na
new dynamic(), więc nie zezwalamy nanew()zdynamicjako typ docelowy. - Krotki: Mają to samo znaczenie, co tworzenie obiektu za pomocą typu bazowego.
- Wszystkie inne typy, które nie są dozwolone w object_creation_expression, są również wykluczone, na przykład, typy wskaźników.
-
typy wyliczenia:
Wady
Wystąpiły pewne obawy związane z new przypisanym do wartości docelowych, tworząc nowe kategorie zmian niezgodności, ale mamy już to z null i default, a to nie było znaczącym problemem.
Alternatywy
Większość skarg dotyczących typów zbyt długich do zduplikowania w inicjowaniu pola dotyczy argumentów typu , a nie samego typu; możemy wywnioskować tylko argumenty typu w niektórych przypadkach, takich jak new Dictionary(...), i wywnioskować je lokalnie z kontekstu argumentów lub inicjatora kolekcji.
Pytania
- Czy powinniśmy zabraniać użycia w drzewach wyrażeń? (nie)
- Jak funkcja współdziała z argumentami
dynamic? (bez specjalnego traktowania) - Jak funkcja IntelliSense powinna działać z
new()? (tylko wtedy, gdy istnieje jeden typ docelowy)
Spotkania projektowe
C# feature specifications