Aracılığıyla paylaş


Hedef türü new ifadeleri

Not

Bu makale bir özellik belirtimidir. Belirtim, özelliğin tasarım belgesi olarak görev alır. Önerilen belirtim değişikliklerini ve özelliğin tasarımı ve geliştirilmesi sırasında gereken bilgileri içerir. Bu makaleler, önerilen belirtim değişiklikleri son haline getirilene ve geçerli ECMA belirtimine dahil edilene kadar yayımlanır.

Özellik belirtimi ile tamamlanan uygulama arasında bazı tutarsızlıklar olabilir. Bu farklılıklar, ilgili dil tasarım toplantısı (LDM) notlarındakaydedilir.

Özellik belirtimlerini C# dil standardına benimseme işlemi hakkında daha fazla bilgi edinmek için belirtimleri makalesinde bulabilirsiniz.

Şampiyon konusu: https://github.com/dotnet/csharplang/issues/100

Özet

Tür bilindiğinde, oluşturucular için tür belirtimi gerekmez.

Motivasyon

Tipi yinelemeden alan başlatmaya izin verin.

Dictionary<string, List<int>> field = new() {
    { "item1", new() { 1, 2, 3 } }
};

Kullanımdan çıkarılabileceği durumda türü atlamaya izin verin.

XmlReader.Create(reader, new() { IgnoreWhitespace = true });

Tür belirtmeden bir nesne örneği oluşturma.

private readonly static object s_syncObj = new();

Şartname

target_typed_new türünde, object_creation_expression içindeki türü isteğe bağlı olan yeni bir söz dizimsel form kabul edildi.

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?
    ;

target_typed_new ifadesinin türü yoktur. Ancak, bir target_typed_new ifadedeki her türe örtük bir dönüştürme olan yeni bir nesne oluşturma dönüştürmesi vardır.

Tbir hedef türü verildiğinde, T örneği System.Nullableise T0 türü, T'nin temel türüdür. Aksi takdirde T0Tolur. T türüne dönüştürülen bir target_typed_new ifadesinin anlamı, tür olarak T0 belirten ilgili bir object_creation_expression anlamı ile aynıdır.

Bir target_typed_new birli veya ikili işleçte işlenen olarak kullanılıyorsa ya da nesne oluşturma dönüşümünetabi olmadığı bir yerde kullanılıyorsa, bu bir derleme zamanı hatasıdır.

Açık Sorun: temsilcilere ve tюplere hedef tür olarak izin vermeli miyiz?

Yukarıdaki kurallar temsilciler (başvuru türü) ve tanımlama kümeleri (yapı türü) içerir. Her iki tür de oluşturulabilir olsa da, tür çıkarılabilirse, anonim bir işlev veya demet değişmez değeri zaten kullanılabilir.

(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

Çeşitli

Belirtimin sonuçları şunlardır:

  • throw new() izin verilir (hedef türü System.Exception)
  • İkili işleçlerle hedef türü new kullanımı izin verilmez.
  • Hedef alacak bir tür olmadığında buna izin verilmez: tekli operatörler, bir foreachkoleksiyonu, using'de, bir yapılandırmada, await ifadesinde, anonim tür özelliği olarak (new { Prop = new() }), lock ifadesinde, sizeof'de, fixed ifadesinde, üye erişiminde (new().field), dinamik olarak dağıtılan bir işlemde (someDynamic.Method(new())), bir LINQ sorgusunda, is operatörünün işleneni olarak, ?? operatörünün sol işleneni olarak ...
  • Ayrıca refolarak da izin verilmez.
  • Dönüştürme hedefi olarak aşağıdaki tür türlerine izin verilmez
    • Enum türleri:new() çalışır (new Enum() varsayılan değeri vermek için çalıştığı gibi), ancak oluşturucuya sahip olmadıkları için enum türleri new(1) çalışmaz.
    • Arabirimi türleri: Bu, COM türleri için karşılık gelen oluşturma ifadesiyle aynı şekilde çalışır.
    • Dizi türleri: dizilerin uzunluğunu belirtmek için özel bir söz dizimi gerekir.
    • dinamik :new dynamic()izin vermediğimizden, hedef tür olarak dynamicnew() izin vermiyoruz.
    • tuple'lar: Bunlar, temel türü kullanarak bir nesne oluşturmayla aynı anlama gelir.
    • object_creation_expression izin verilmeyen diğer tüm türler de, örneğin işaretçi türleri hariç tutulur.

Dezavantaj -ları

Hedef-türü new ile yeni bozucu değişiklik kategorileri oluşturma konusunda bazı endişeler vardı, ancak bunu zaten null ve defaultile yaptık ve bu önemli bir sorun oluşturmadı.

Alternatif

Alan başlatmada türlerin çoğaltılamayacak kadar uzun olmasına ilişkin şikayetlerin çoğu, türün kendisi değil tür bağımsız değişkenleriyle ilgilidir; yalnızca new Dictionary(...) (veya benzeri) gibi tür bağımsız değişkenlerini çıkarabiliyorduk ve tür bağımsız değişkenlerini bağımsız değişkenlerden veya koleksiyon başlatıcısından yerel olarak çıkarabiliyorduk.

Sorular

  • İfade ağaçlarında kullanımı yasaklasak mı? (hayır)
  • Özellik dynamic bağımsız değişkenleriyle nasıl etkileşim kurar? (özel işlem yapılmaz)
  • IntelliSense new()ile nasıl çalışmalıdır? (yalnızca tek bir hedef türü olduğunda)

Tasarım toplantıları