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, dil tasarım toplantısı (LDM) notlarındabelirtilir.
Özellik belirtimlerini C# dil standardına benimseme işlemi hakkında daha fazla bilgi edinmek için
Şampiyon sorunu: https://github.com/dotnet/csharplang/issues/3301
Özet
Bu teklif, C# dilindeki partial
yöntemlerinin imzalarıyla ilgili tüm kısıtlamaları kaldırmayı amaçlar. Amaç, bu yöntemlerin kaynak oluşturucularla çalışabileceği senaryo kümesini genişletmek ve C# yöntemleri için daha genel bir bildirim formu olmaktır.
Ayrıca bkz. özgün kısmi yöntem belirtimi (§15.6.9).
Motivasyon
C# geliştiricilerin yöntemleri bildirimlere ve tanımlara/uygulamalara bölmesine yönelik sınırlı desteğe sahiptir.
partial class C
{
// The declaration of C.M
partial void M(string message);
}
partial class C
{
// The definition of C.M
partial void M(string message) => Console.WriteLine(message);
}
partial
yöntemlerin davranışlarından biri, tanım olmadığında dilin partial
yöntemine yapılan çağrıları silmesidir. Temelde koşulun false olarak değerlendirildiği bir [Conditional]
yöntemi çağrısı gibi davranır.
partial class D
{
partial void M(string message);
void Example()
{
M(GetIt()); // Call to M and GetIt erased at compile time
}
string GetIt() => "Hello World";
}
Bu özelliğin özgün motivasyonu, tasarımcı tarafından oluşturulan kod biçiminde kaynak oluşturmaydı. Kullanıcılar, oluşturulan kodun bazı yönlerini bağlamak istediklerinden, oluşturulan kodu sürekli düzenliyorlardı. Bileşenler başlatıldıktan sonra, özellikle Windows Forms başlatma sürecinin en önemli bölümleri.
Tasarımcının kodu yeniden oluşturmasına neden olan herhangi bir eylem kullanıcı düzenlemesinin silinmesine neden olabileceğinden oluşturulan kodu düzenlemek hataya neden oldu.
partial
yöntemi, tasarımcıların kancaları partial
yöntemler biçiminde yaymalarına olanak sağladığından bu gerilimi azaltmıştı.
Tasarımcılar partial void OnComponentInit()
gibi kancalar yayabilir ve geliştiriciler bunlar için bildirim tanımlayabilir veya tanımlamayabilir. Her iki durumda da oluşturulan kod derlenecekti ve işlemle ilgilenen geliştiriciler gerektiğinde bağlanabiliyordu.
Bu, kısmi yöntemlerin çeşitli kısıtlamaları olduğu anlamına gelir:
- Dönüş türü
void
olmalıdır. -
out
parametreleri bulunamaz. - Herhangi bir şekilde erişilebilir değil (örtük olarak
private
).
Çağrı sitesi silindiğinde dilin kod yayabilmesi gerektiğinden bu kısıtlamalar vardır. Silinebilecekleri için private
, derleme meta verilerinde üyenin maruz kalamayacağı tek erişilebilirliktir. Bu kısıtlamalar, partial
yöntemlerinin uygulanabileceği senaryo kümesini sınırlamaya da hizmet eder.
Buradaki teklif, partial
yöntemleriyle ilgili mevcut kısıtlamaların tümünü kaldırmaktır. Temelde out
parametrelerine, geçersiz olmayan dönüş türlerine veya herhangi bir erişilebilirlik türüne sahip olmalarına izin verin. Bu tür partial
bildirimleri, bir tanımın mevcut olması gerektiği gereksinimini ekler. Bu, dilin arama sitelerini silmenin etkisini göz önünde bulundurması gerekmediği anlamına gelir.
Bu, partial
yöntemlerin katılabileceği oluşturucu senaryoları kümesini genişletir ve bu nedenle kaynak oluşturucular özelliğimizle güzel bir şekilde bağlantı kurar. Örneğin, bir regex aşağıdaki desen kullanılarak tanımlanabilir:
[RegexGenerated("(dog|cat|fish)")]
partial bool IsPetMatch(string input);
Bu, hem geliştiriciye oluşturucuları seçmenin basit bir bildirimli yolunu sunar hem de oluşturuculara, oluşturulan çıkışlarını yönlendirmek için kaynak kodunda bakılması gereken çok kolay bir bildirim kümesi verir.
Bunu, bir oluşturucunun aşağıdaki kod parçacığını bağlama zorluğuyla karşılaştırın.
var regex = new RegularExpression("(dog|cat|fish)");
if (regex.IsMatch(someInput))
{
}
Derleyicinin oluşturucuların kod bağlamayı değiştirmesine izin vermediği göz önünde bulundurulduğunda, bu düzen oluşturucular için neredeyse imkansız olacaktır.
IsMatch
uygulamasında yansımaya başvurmaları veya kullanıcıların çağrı noktalarını yeni bir yöntemle değiştirmelerini + regex'i, dize sabitini bir bağımsız değişken olarak geçecek şekilde yeniden düzenlemelerini istemeleri gerekir. Oldukça dağınık.
Ayrıntılı Tasarım
Dil, partial
yöntemlerin açık bir erişilebilirlik değiştiricisi ile açıklanmasına izin vermek için değişecek. Bu, private
, public
vb. olarak etiketlenebileceği anlamına gelir.
bir partial
yönteminde açık bir erişilebilirlik değiştiricisi olduğunda, dil, erişilebilirlik private
olsa bile bildirimin eşleşen bir tanımı olmasını gerektirir:
partial class C
{
// Okay because no definition is required here
partial void M1();
// Okay because M2 has a definition
private partial void M2();
// Error: partial method M3 must have a definition
private partial void M3();
}
partial class C
{
private partial void M2() { }
}
Ayrıca dil, açık erişilebilirliği olan bir partial
yönteminde nelerin görüntülenebileceğine ilişkin tüm kısıtlamaları kaldırır. Bu tür bildirimler geçersiz olmayan dönüş türleri, out
parametreleri, extern
değiştirici vb. içerebilir... Bu imzalar C# dilinin tüm ifadelerine sahip olacaktır.
partial class D
{
// Okay
internal partial bool TryParse(string s, out int i);
}
partial class D
{
internal partial bool TryParse(string s, out int i) { ... }
}
Bu açıkça partial
yöntemlerin overrides
ve interface
uygulamalarına katılmasını sağlar:
interface IStudent
{
string GetName();
}
partial class C : IStudent
{
public virtual partial string GetName();
}
partial class C
{
public virtual partial string GetName() => "Jarde";
}
Derleyici, bir partial
metodu yasadışı bir öğe içerdiğinde yaydığı hatayı, temelde şunu belirtmek üzere değiştirecektir:
Açık erişilebilirliği olmayan bir
ref
yöntemindepartial
kullanılamaz
Bu, bu özelliği kullanırken geliştiricileri doğru yönde yönlendirmeye yardımcı olur.
Kısıtlama -ları:
- Açık erişilebilirliği olan
partial
bildirimlerinin bir tanımı olmalıdır -
partial
bildirimleri ve tanım imzaları tüm yöntem ve parametre değiştiricilerinde eşleşmelidir. Farklı olabilecek tek yönler parametre adları ve öznitelik listeleridir (bu yeni değil,partial
yöntemlerin mevcut bir gereksinimidir).
Sorular
kısmi tüm üyelerde
Kaynak oluşturuculara daha kullanışlı hale getirdiğimiz partial
'ı, tüm sınıf üyeleri üzerinde de çalışacak şekilde genişletmeli miyiz? Örneğin, partial
oluşturucuları, işleçleri vb. bildirebilmemiz gerekir...
Çözünürlük Fikir mantıklıdır ancak bu noktada C# 9 takviminde gereksiz özellik yığılmasını önlemeye çalışıyoruz. Modern kaynak oluşturucularla çalışacak şekilde özelliği genişletme sorununu acil olarak çözmek istiyorsunuz.
C# 10 sürümü için partial
diğer üyeleri destekleyecek şekilde genişletilmesi dikkate alınacaktır. Bu uzantıyı dikkate almamız muhtemel görünüyor. Bu, etkin bir teklif olmaya devam eder, ancak henüz uygulanmamıştır.
Kısmi yerine soyut kullanma
Bu teklifin temel noktası, bir bildirimin karşılık gelen bir tanımı / uygulaması olmasını sağlamaktır. Geliştiriciyi bir uygulamaya sahip olmayı düşünmeye zorlayan bir dil anahtar sözcüğü olduğundan abstract
kullanalım mı?
Çözüm Bu konuda sağlıklı bir tartışma vardı ama sonunda buna karşı karar verildi. Evet, gereksinimler tanıdıktır ancak kavramlar önemli ölçüde farklıdır. Geliştiricinin, aslında sanal yuvalar oluşturmadıkları halde, bunu yaptıklarına inanmasına kolayca yol açabilir.
C# feature specifications