Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
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ının (LDM) notlarındakaydedilir.
Özellik belirtimlerini C# dil standardına benimseme işlemi hakkında daha fazla bilgi edinmek için belirtimleri makalesinde bulabilirsiniz.
Şampiyon sorunu: https://github.com/dotnet/csharplang/issues/2765
Özet
bir compilation_unitnamespace_member_declaration'lerinden hemen önce (kaynak dosya gibi) deyimleri dizisinin gerçekleşmesine izin.
Semantik, deyimlerinin böyle bir dizisi varsa, gerçek yöntem adını modüle eden aşağıdaki tür bildiriminin yayılacağıdır:
partial class Program
{
static async Task Main(string[] args)
{
// statements
}
}
Ayrıca bkz. https://github.com/dotnet/csharplang/issues/3117.
Motivasyon
En basit programları bile çevreleyen belirli bir standart kod vardır, çünkü açık bir Main
yöntemine ihtiyaç vardır. Bu, dil öğrenimini ve program netliğini engelliyor gibi görünüyor. Bu nedenle, özelliğin birincil hedefi, öğrenenler ve kodun netliği için C# programlarına gereksiz altyapı kodu olmadan izin vermektir.
Ayrıntılı tasarım
Sözdizimi
Tek ek söz dizimi, namespace_member_declaration'lerden hemen önce bir derleme biriminde deyimi dizisine izin vermektir:
compilation_unit
: extern_alias_directive* using_directive* global_attributes? statement* namespace_member_declaration*
;
Yalnızca bir compilation_unit, ifadeyes sahip olabilir.
Örnek:
if (args.Length == 0
|| !int.TryParse(args[0], out int n)
|| n < 0) return;
Console.WriteLine(Fib(n).curr);
(int curr, int prev) Fib(int i)
{
if (i == 0) return (1, 0);
var (curr, prev) = Fib(i - 1);
return (curr + prev, curr);
}
Anlambilim
Programın herhangi bir derleme biriminde herhangi bir üst düzey deyim varsa, anlamı genel ad alanında bir Program
sınıfının Main
yönteminin blok gövdesinde aşağıdaki gibi birleştirilmiş gibi olur:
partial class Program
{
static async Task Main(string[] args)
{
// statements
}
}
Tür "Program" olarak adlandırılır, bu nedenle kaynak koddan adla başvurulabilir. Kısmi bir tür olduğundan, kaynak koddaki "Program" adlı bir türün de kısmi olarak bildirilmesi gerekir.
Ancak yöntem adı "Main" yalnızca çizim amacıyla kullanılır, derleyici tarafından kullanılan gerçek ad uygulamaya bağımlıdır ve yönteme kaynak koddan adla başvurulamaz.
yöntemi, programın giriş noktası olarak belirlenir. Kurallara göre giriş noktası adayı olabilecek şekilde açıkça bildirilen yöntemler göz ardı edilir. Bu durumda bir uyarı bildirilir. Üst düzey deyimler olduğunda -main:<type>
derleyici anahtarını belirtmek bir hatadır.
Giriş noktası yönteminin her zaman string[] args
tek bir resmi parametresi vardır. Uygulama başlatıldığında belirtilen komut satırı argümanlarını içeren bir string[]
argümanı oluşturur ve geçirir.
string[]
bağımsız değişkeni hiçbir zaman null değildir, ancak hiçbir komut satırı bağımsız değişkeni belirtilmemişse uzunluğu sıfır olabilir. 'args' parametresi üst düzey deyimlerin kapsamındadır ve bunların dışında kapsam içinde değildir. Normal ad çakışması/gölgeleme kuralları uygulanır.
Asenkron işlemlere, normal bir asenkron giriş noktası yöntemi içindeki ifadelere izin verilen ölçüde, en üst düzey ifadelerde de izin verilir. Ancak, bunlar gerekli değildir, await
ifadeleri ve diğer zaman uyumsuz işlemler atlanırsa, hiçbir uyarı üretilmez.
Oluşturulan giriş noktası yönteminin imzası, en üst düzey deyimler tarafından kullanılan işlemlere göre aşağıdaki gibi belirlenir:
Asenkron-işlemler\İfade-ile-dönüş | Güncel | Yok |
---|---|---|
Sunum | static Task<int> Main(string[] args) |
static Task Main(string[] args) |
Yok | static int Main(string[] args) |
static void Main(string[] args) |
Yukarıdaki örnek aşağıdaki $Main
yöntemi bildirimini verir:
partial class Program
{
static void $Main(string[] args)
{
if (args.Length == 0
|| !int.TryParse(args[0], out int n)
|| n < 0) return;
Console.WriteLine(Fib(n).curr);
(int curr, int prev) Fib(int i)
{
if (i == 0) return (1, 0);
var (curr, prev) = Fib(i - 1);
return (curr + prev, curr);
}
}
}
Aynı zamanda şuna benzer bir örnek:
await System.Threading.Tasks.Task.Delay(1000);
System.Console.WriteLine("Hi!");
şunu üretebilir:
partial class Program
{
static async Task $Main(string[] args)
{
await System.Threading.Tasks.Task.Delay(1000);
System.Console.WriteLine("Hi!");
}
}
Şuna benzer bir örnek:
await System.Threading.Tasks.Task.Delay(1000);
System.Console.WriteLine("Hi!");
return 0;
şunu verir:
partial class Program
{
static async Task<int> $Main(string[] args)
{
await System.Threading.Tasks.Task.Delay(1000);
System.Console.WriteLine("Hi!");
return 0;
}
}
Ve şuna benzer bir örnek:
System.Console.WriteLine("Hi!");
return 2;
şunu sağlayabilir:
partial class Program
{
static int $Main(string[] args)
{
System.Console.WriteLine("Hi!");
return 2;
}
}
Üst düzey yerel değişkenlerin ve yerel işlevlerin kapsamı
En üst düzey yerel değişkenler ve işlevler oluşturulan giriş noktası yöntemine "sarmalanmış" olsa da, her derleme ünitesinde program genelinde kapsam içinde olmaları gerekir. Basit ad değerlendirmesi amacıyla, genel ad alanına ulaşıldıktan sonra:
- Öncelikle, oluşturulan giriş noktası yöntemi içinde adı değerlendirme girişiminde bulunulur ve yalnızca bu girişim başarısız olursa başka bir adım atılır.
- Genel ad alanı bildirimi içinde "normal" değerlendirme gerçekleştirilir.
Bu, genel ad alanı içinde bildirilen ad alanlarının ve türlerin ad gölgelenmesine ve içeri aktarılan adların gölgelenmesine yol açabilir.
Basit ad değerlendirmesi üst düzey deyimlerin dışında gerçekleşirse ve değerlendirme üst düzey bir yerel değişken veya işlev verirse, bu bir hataya yol açmalıdır.
Bu şekilde, gelecekteki "Üst düzey işlevler" (https://github.com/dotnet/csharplang/issues/31172 senaryosu) ile daha iyi başa çıkan becerimizi koruyoruz ve yanlışlıkla destekleneceklerine inanan kullanıcılara yararlı tanılamalar sunabiliyoruz.
C# feature specifications