Aracılığıyla paylaş


Aşırı Yükleme Çözümleme Önceliği

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, ilgilidil tasarım toplantısı (LDM) notlarında yakalanır.

Ö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/7706

Özet

API yazarlarının, belirli API'leri kullanmaları için API tüketicilerini yönlendirmelerine olanak tanıyan ve bir tür içindeki aşırı yüklemelerin göreli önceliğini ayarlamak için kullanılabilecek yeni bir öznitelik (System.Runtime.CompilerServices.OverloadResolutionPriority) tanıtıyoruz. Bu, normalde belirsiz olarak kabul edilen veya C#'ın aşırı yükleme çözümleme kuralları tarafından seçilmeyecek API'lerin kullanımını kolaylaştırır.

Motivasyon

API yazarları genellikle bir üyenin kullanımdan kaldırıldıktan sonra ne yapacağına ilişkin bir sorunla karşılaşır. Geriye dönük uyumluluk amacıyla, birçok kişi ikili dosyaları çalışma zamanında yükselten kullanıcıların hatalarını önlemek için ObsoleteAttribute ayarı hata olarak kalacak şekilde mevcut üyeyi muhafaza eder. Bu özellikle eklentinin yazarının eklentinin çalıştığı ortamı denetlemediği eklenti sistemlerine isabet eder. Ortamı oluşturan, eski bir yöntemi mevcut tutmak isteyebilir, ancak yeni geliştirilen tüm kodlar için bu yönteme erişimi engelleyebilir. Ancak tek başına ObsoleteAttribute yeterli değildir. Tür veya üye hala aşırı yükleme çözümlemesinde görünürdür ve mükemmel bir alternatif mevcutken istenmeyen aşırı yükleme çözümleme hatalarına neden olabilir. Ancak bu alternatif ya kullanım dışı bırakılmış üyeyle bazen karışabilir ya da kullanım dışı bırakılmış üyenin varlığı, iyi üyeyi hiç dikkate almadan aşırı yükleme çözümlemesinin erken sona ermesine neden olabilir. Bu amaçla API yazarlarının, api yüzey alanlarını geliştirebilmeleri ve kullanıcı deneyimini tehlikeye atmadan yüksek performanslı API'lere yönlendirebilmeleri için, belirsizliği çözme konusunda aşırı yükleme çözümüne yol göstermesi için bir yol bulmak istiyoruz.

Temel Sınıf Kitaplıkları (BCL) ekibi, bunun yararlı olduğu durumlar için çeşitli örnekler içerir. Bazı (varsayımsal) örnekler şunlardır:

  • Doğrulanmakta olan ifadeyi elde etmek için Debug.Assert'i kullanan ve iletiye dahil edilebilmesi için mevcut aşırı yüklemeden daha fazla tercih edilmesi gereken bir CallerArgumentExpression aşırı yüklemesi oluşturma.
  • string.IndexOf(string, StringComparison = Ordinal)yerine string.IndexOf(string)'ı tercih etme. Bu, olası bir hataya neden olan değişiklik olarak ele alınmalıdır, ancak bunun daha iyi bir varsayılan olduğu ve kullanıcının amaçladığı gibi olma olasılığının daha yüksek olduğu düşünülmüştür.
  • Bu teklifin ve CallerAssemblyAttribute birleşimi, çağrı yapan kimliğin örtük olduğu yöntemlerin pahalı yığın yürüyüşlerinden kaçınmalarına olanak tanır. Assembly.Load(AssemblyName) bunu bugün yapar ve çok daha verimli olabilir.
  • Microsoft.Extensions.Primitives.StringValues, hem string hem de string[]için örtük bir dönüşümü ifşa eder. Bu, hem params string[] hem de params ReadOnlySpan<string> aşırı yüklemeleri olan bir yönteme geçirildiğinde belirsiz olduğu anlamına gelir. Bu öznitelik, belirsizliği önlemek için aşırı yüklemelerden birine öncelik vermek için kullanılabilir.

Ayrıntılı Tasarım

Aşırı yükleme çözümleme önceliği

Bir yöntem grubunu çözümleme işlemi sırasında kullanılan overload_resolution_priorityyeni bir kavram tanımlarız. overload_resolution_priority 32 bit tamsayı değeridir. Tüm yöntemlerin varsayılan olarak overload_resolution_priority değeri 0'dır ve bu yöntemlere OverloadResolutionPriorityAttribute uygulanarak değiştirilebilir. C# belirtiminin bölümünün §12.6.4.1 kısmını aşağıdaki şekilde güncelliyoruz (değişiklikler kalınolarak).

Aday işlev üyeleri ve bağımsız değişken listesi belirlendikten sonra, her durumda en iyi işlev üyesinin seçimi aynıdır:

  • İlk olarak, aday işlev üyeleri kümesi, verilen bağımsız değişken listesine uygun işlev üyeleriyle sınırlanır (§12.6.4.2). Bu azaltılmış küme boşsa, derleme zamanı hatası oluşur.
  • Ardından, azaltılmış aday üye kümesi, türleri belirtilerek gruplandırılır. Her grubun içinde:
    • İşlev üyesi adayları overload_resolution_prioritytarafından sıralanır. Üye bir geçersiz kılma ise, overload_resolution_priority bu üyenin en az türetilmiş olan bildiriminden kaynaklanır.
    • Tanımlayıcı tür grubundaki en yüksek değerden daha düşük overload_resolution_priority sahibi olan tüm üyeler kaldırılır.
  • Azaltılan gruplar, geçerli aday işlev üyelerinin son kümesine yeniden eklenir.
  • Ardından, uygun aday işlev üyeleri kümesinden en iyi işlev üyesi bulunur. Kümede yalnızca bir işlev üyesi varsa, bu işlev üyesi en iyi işlev üyesidir. Aksi takdirde, her işlev üyesinin §12.6.4.3içindeki kurallar kullanılarak diğer tüm işlev üyeleriyle karşılaştırılması koşuluyla, en iyi işlev üyesi verilen bağımsız değişken listesiyle ilgili olarak diğer tüm işlev üyelerinden daha iyi olan tek işlev üyesidir. Diğer tüm işlev üyelerinden daha iyi olan tam olarak bir işlev üyesi yoksa, işlev üyesi çağrısı belirsizdir ve bağlama zamanı hatası oluşur.

Örneğin, bu özellik aşağıdaki kod parçacığının "Dizi" yerine "Span" yazdırmasına neden olabilir:

using System.Runtime.CompilerServices;

var d = new C1();
int[] arr = [1, 2, 3];
d.M(arr); // Prints "Span"

class C1
{
    [OverloadResolutionPriority(1)]
    public void M(ReadOnlySpan<int> s) => Console.WriteLine("Span");
    // Default overload resolution priority
    public void M(int[] a) => Console.WriteLine("Array");
}

Bu değişikliğin etkisi, en türetilmiş türler için yapılan azaltma işlemine benzer şekilde, aşırı yükleme çözümleme önceliği için nihai bir azaltma eklememizdir. Bu ayıklama, aşırı yükleme çözümleme işleminin en sonunda gerçekleştiğinden, temel türün üyelerini türetilmiş herhangi bir türe göre daha yüksek öncelikli yapamayacağı anlamına gelir. Bu kasıtlıdır ve bir temel türün türetilmiş bir türden her zaman daha iyi olmaya çalışabileceği bir silahlanma yarışının oluşmasını önler. Örneğin:

using System.Runtime.CompilerServices;

var d = new Derived();
d.M([1, 2, 3]); // Prints "Derived", because members from Base are not considered due to finding an applicable member in Derived

class Base
{
    [OverloadResolutionPriority(1)]
    public void M(ReadOnlySpan<int> s) => Console.WriteLine("Base");
}

class Derived : Base
{
    public void M(int[] a) => Console.WriteLine("Derived");
}

Negatif sayıların kullanılmasına izin verilir ve belirli bir aşırı yüklemeyi diğer tüm varsayılan aşırı yüklemelerden daha kötü olarak işaretlemek için kullanılabilir.

Bir üyenin overload_resolution_priority, bu üyenin en az türetilmiş bildiriminden gelir. overload_resolution_priority, bir tür üyesinin uygulayabileceği arabirim üyelerinden devralınmıyor veya çıkarılmaz ve Mxarabirim üyesi uygulayan bir üye Mi verildiğinde, Mx ve Mi farklı overload_resolution_prioritiessahipse uyarı verilmez.

NOT: Bu kuralın amacı, params değiştiricinin davranışını çoğaltmaktır.

System.Runtime.CompilerServices.OverloadResolutionPriorityAttribute

BCL için aşağıdaki özniteliği tanıtıyoruz:

namespace System.Runtime.CompilerServices;

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
public sealed class OverloadResolutionPriorityAttribute(int priority) : Attribute
{
    public int Priority => priority;
}

C# dilindeki tüm yöntemlerin ile ilişkilendirilmediği sürece varsayılan OverloadResolutionPriorityAttribute 0'dır. Eğer bu öznitelik onlara atanmışsa, aşırı yük çözümleme önceliği, özniteliğin ilk bağımsız değişkenine sağlanan tamsayı değeridir.

aşağıdaki konumlara OverloadResolutionPriorityAttribute uygulanması bir hatadır:

  • Dizin oluşturucu olmayan özellikler
  • Özellik, dizin oluşturucu veya olay erişimcileri
  • Dönüştürme işleçleri
  • Lambda
  • Yerel işlevler
  • Sonlandırıcılar
  • Statik oluşturucular

Meta verilerde bu konumlarda karşılaşılan öznitelikler C# tarafından yoksayılır.

OverloadResolutionPriorityAttribute'ın, önceliğin bir üyenin en az türetilmiş bildiriminden okunduğu için, temel bir metodun geçersiz kılınması gibi dikkate alınmayacağı bir konuma uygulanması hatadır.

NOT: Bu, params değiştiricinin davranışından kasıtlı olarak farklıdır ve bu, yoksayıldığında yeniden belirtilmesine veya eklenmesine olanak tanır.

Üyelerin çağrılabilirliği

OverloadResolutionPriorityAttribute için önemli bir uyarı, belirli üyelerin kaynak koddan etkin bir şekilde çağrılamaz hale gelebileceğidir. Örneğin:

using System.Runtime.CompilerServices;

int i = 1;
var c = new C3();
c.M1(i); // Will call C3.M1(long), even though there's an identity conversion for M1(int)
c.M2(i); // Will call C3.M2(int, string), even though C3.M1(int) has less default parameters

class C3
{
    public void M1(int i) {}
    [OverloadResolutionPriority(1)]
    public void M1(long l) {}

    [Conditional("DEBUG")]
    public void M2(int i) {}
    [OverloadResolutionPriority(1), Conditional("DEBUG")]
    public void M2(int i, [CallerArgumentExpression(nameof(i))] string s = "") {}

    public void M3(string s) {}
    [OverloadResolutionPriority(1)]
    public void M3(object o) {}
}

Bu örnekler için varsayılan öncelik aşırı yüklemeleri etkili bir şekilde işlevsiz hale gelir ve ancak ekstra çaba gerektiren birkaç adımı izleyerek çağrılabilir.

  • Metodu bir delegeye dönüştürme ve ardından bu delegeyi kullanma.
    • M3(object)'ın M3(string)'e göre önceliklendirildiği bazı başvuru türü varyans senaryoları için bu strateji başarısız olur.
    • koşullu yöntemler temsilcilere dönüştürülemediği için M2gibi koşullu yöntemler de bu stratejiyle çağrılamaz.
  • eşleşen imza aracılığıyla çağırmak için UnsafeAccessor çalışma zamanı özelliğini kullanma.
  • Yönteme bir başvuru elde etmek ve ardından onu çağırmak için manuel olarak yansımayı kullanma.
  • Yeniden derlenmemiş kod eski yöntemleri çağırmaya devam eder.
  • El yazısı IL, seçtiği her şeyi belirtebilir.

Açık Sorular

Uzantı yöntemi gruplandırma (yanıt)

Şu anda belirtildiği gibi, uzantı yöntemleri yalnızca kendi türü içindeönceliğe göre sıralanır. Örneğin:

new C2().M([1, 2, 3]); // Will print Ext2 ReadOnlySpan

static class Ext1
{
    [OverloadResolutionPriority(1)]
    public static void M(this C2 c, Span<int> s) => Console.WriteLine("Ext1 Span");
    [OverloadResolutionPriority(0)]
    public static void M(this C2 c, ReadOnlySpan<int> s) => Console.WriteLine("Ext1 ReadOnlySpan");
}

static class Ext2
{
    [OverloadResolutionPriority(0)]
    public static void M(this C2 c, ReadOnlySpan<int> s) => Console.WriteLine("Ext2 ReadOnlySpan");
}

class C2 {}

Uzantı üyeleri için aşırı yükleme çözümlemesi yaparken, türü bildirerek sıralamamalı ve bunun yerine aynı kapsamdaki tüm uzantıları dikkate almamalı mıydık?

Cevap

Her zaman gruplayacağız. Yukarıdaki örnek Ext2 ReadOnlySpan'ı yazdıracak.

Geçersiz kılma işlemlerinde öznitelik devralma (yanıtlandı)

Öznitelik devralınmalı mı? Aksi takdirde, üstün gelen üyenin önceliği nedir?
Öznitelik bir sanal üyede belirtilirse, özniteliği yinelemek için bu üyenin geçersiz kılınması gerekir mi?

Cevap

Öznitelik devralındı olarak işaretlenmez. Bir üyenin aşırı yükleme çözümleme önceliğini belirlemek için en az türetilmiş bildirimine bakacağız.

Geçersiz kılma sırasında uygulama hatası veya uyarısı (çözüldü)

class Base
{
    [OverloadResolutionPriority(1)] public virtual void M() {}
}
class Derived
{
    [OverloadResolutionPriority(2)] public override void M() {} // Warn or error for the useless and ignored attribute?
}

Uygulamayı göz ardı eden bir bağlamda, örneğin bir geçersiz kılma sırasında, OverloadResolutionPriorityAttribute uygulaması hakkında ne yapmalıyız?

  1. Hiçbir şey yapma, sessizce görmezden gelinsin.
  2. Özniteliğin yoksayılacağına dair bir uyarı verme.
  3. Özniteliğin izin verilmediğini belirten bir hata oluşturun.

Gelecekte bu özniteliği belirtmek için bir geçersiz kılmaya izin vermek isteyebileceğimiz bir alan olabileceğini düşündüğümüzde, 3 en temkinli yaklaşımdır.

Cevap

3 ile devam edeceğiz ve göz ardı edileceği konumlarda uygulamayı engelleyeceğiz.

Örtük arabirim uygulaması (yanıtlandı)

Örtük arabirim uygulamasının davranışı ne olmalıdır? OverloadResolutionPrioritybelirtmek gerekli mi? Öncelikli olmayan örtük bir uygulamayla karşılaştığında derleyicinin davranışı ne olmalıdır? Bu neredeyse kesinlikle gerçekleşecek, çünkü bir arabirim kitaplığı güncellenebilir, ancak bir uygulama olmayabilir. Buradaki params içeren önceki teknik, değeri belirtmemek ve bu değeri taşımamaktır.

using System;

var c = new C();
c.M(1, 2, 3); // error CS1501: No overload for method 'M' takes 3 arguments
((I)c).M(1, 2, 3);

interface I
{
    void M(params int[] ints);
}

class C : I
{
    public void M(int[] ints) { Console.WriteLine("params"); }
}

Seçeneklerimiz şunlardır:

  1. paramsizleyin. OverloadResolutionPriorityAttribute otomatik olarak aktarılmaz veya belirtilmesi gerekli değildir.
  2. Özelliği örtük olarak aktarın.
  3. özniteliğini örtük olarak taşımayın, çağrı sitesinde belirtilmesi gerekir.
    1. Bu ek bir soru getirir: Derleyici derlenmiş başvurularla bu senaryoyla karşılaştığında davranış ne olmalıdır?

Cevap

1 ile gideceğiz.

Diğer uygulama hataları (Yanıtlandı)

gibi gibi onaylanması gereken birkaç konum daha vardır. Bunlar şunlardır:

  • Dönüştürme işleçleri - Belirtim hiçbir zaman dönüştürme işleçlerinin aşırı yükleme çözümlemesi gerçekleştirdiğini söylemez, bu nedenle uygulama bu üyeler üzerinde uygulamayı engeller. Bu onaylanmalı mı?
  • Lambdalar - Benzer şekilde, lambdalar hiçbir zaman aşırı yüklemeye tabi tutulmaz, bu nedenle uygulamada bunlar engellenir. Bu onaylanmalı mı?
  • Yıkıcılar - şu anda yine engellendi.
  • Statik oluşturucular - yeniden, halen engellenmiş durumda.
  • Yerel işlevler - Bunlar şu anda engellenmez, çünkü aşırı yükleme çözümlemesi , bunları aşırı yükleyemezsiniz. Bu, özniteliği aşırı yüklenmemiş bir türün üyesine uygulandığında hata vermediğimize benzer. Bu davranış doğrulanmalı mı?

Cevap

Yukarıda listelenen tüm konumlar engellenir.

Langversion Davranışı (Yanıtlandı)

Uygulama şu anda yalnızca OverloadResolutionPriorityAttribute uygulandığında langversion hataları veriyor, gerçekte bir şeyi etkilediğinde değil uygulanmalı. Bu karar, BCL'nin şimdi ve zaman içinde bu özniteliği kullanmaya başlayacak API'ler ekleyecek olmasından dolayı alındı; kullanıcı dil sürümünü manuel olarak C# 12 veya daha öncesine ayarlarsa, bu üyeleri görebilir ve langversion davranışımıza bağlı olarak şu sonuçlarla karşılaşabilir:

  • C# <13'teki özniteliği yoksayarsak, API özniteliği olmadan gerçekten belirsiz olduğu için bir belirsizlik hatasıyla karşılaşırız veya;
  • Öznitelik sonucu etkilediğinde hata yaparsak, API'nin kullanılamaz hale geldiği bir hatayla karşılaşırız. Bu özellikle kötü olacak çünkü Debug.Assert(bool), .NET 9'da öncelik sıralamasında geri plana atılıyor.
  • Çözümlemeyi sessizce değiştirirsek, biri özniteliği anlarsa ve diğeri anlamadıysa, farklı derleyici sürümleri arasında farklı davranışlarla karşılaşabilirsiniz.

En ileriye dönük uyumlulukla sonuçlandığı için son davranış seçildi, ancak değişen sonuç bazı kullanıcılar için şaşırtıcı olabilir. Bunu onaylamalı mı yoksa diğer seçeneklerden birini mi seçmeliyiz?

Cevap

1. seçeneği seçeceğiz ve önceki dil versiyonlarındaki özniteliği sessizce yoksayacağız.

Alternatif

Önceki bir teklif, BinaryCompatOnlyAttribute bir yaklaşım belirtmeye çalışıyordu, ancak bu, öğeleri görünürlükten kaldırma konusunda çok katı bir yaklaşım sergiliyordu. Ancak bu, teklifin yararlı olamayacak kadar güçlü (örneğin eski API'lerin test edilmesini önleme) veya özgün hedeflerin bazılarını kaçıracak kadar zayıf olduğu (aksi takdirde belirsiz bir api'nin yeni bir API çağrısı olarak kabul edilebileceği gibi) çok sayıda zor uygulama sorununa sahiptir. Bu sürüm aşağıda tekrarlanmıştır.

BinaryCompatOnlyAttribute Önerisi (kullanım dışı)

BinaryCompatOnlyAttribute

Ayrıntılı tasarım

System.BinaryCompatOnlyAttribute

Yeni bir ayrılmış öznitelik tanıtıyoruz:

namespace System;

// Excludes Assembly, GenericParameter, Module, Parameter, ReturnValue
[AttributeUsage(AttributeTargets.Class
                | AttributeTargets.Constructor
                | AttributeTargets.Delegate
                | AttributeTargets.Enum
                | AttributeTargets.Event
                | AttributeTargets.Field
                | AttributeTargets.Interface
                | AttributeTargets.Method
                | AttributeTargets.Property
                | AttributeTargets.Struct,
                AllowMultiple = false,
                Inherited = false)]
public class BinaryCompatOnlyAttribute : Attribute {}

Bir tür üyesine uygulandığında, bu üye derleyici tarafından her konumda erişilemez olarak değerlendirilir, yani üye aramasına, aşırı yükleme çözümlemesine veya başka bir benzer işleme katkıda bulunmaz.

Erişilebilirlik Etki Alanları

§7.5.3 Erişilebilirlik etki alanlarını aşağıdaki güncelleştiriyoruz:

Üyenin erişilebilirlik etki alanı, üyeye erişime izin verilen program metninin (muhtemelen kopuk) bölümlerinden oluşur. Bir üyenin erişilebilirlik alanını tanımlama amacıyla, bir üye bir tür içinde bildirilmemişse en üst düzey olduğu, başka bir tür içinde bildirilmişse iç içe olduğu söylenir. Ayrıca, bir programın program metni, programın tüm derleme birimlerinde yer alan tüm metin olarak tanımlanır ve bir türün program metni, bu türün type_declarations içinde yer alan tüm metin olarak tanımlanır (büyük olasılıkla, türün içinde iç içe yerleştirilmiş türler dahil).

Önceden tanımlanmış bir türün erişilebilirlik etki alanı (object, intveya doublegibi) sınırsızdır.

Üst düzey ilişkili olmayan tür T (§8.4.4), P bir programda bildirildiğinde erişilebilirlik etki alanı aşağıdaki gibi tanımlanır:

  • T BinaryCompatOnlyAttributeile işaretlenmişse, T'ün erişilebilirlik alanı, P'ün program metni ve P'e başvuran tüm programlar için tamamen ulaşılamaz.
  • T bildirilen erişilebilirliği halka açıksa, T'in erişilebilirlik etki alanı P'nin program metni ve P'e başvuran herhangi bir programdır.
  • T'nin bildirilen erişilebilirliği dahiliyse, T'nin erişilebilirlik etki alanı Pprogram metnidir.

Not: Bu tanımlardan, en üst düzey ilişkisiz türün erişilebilirlik etki alanının her zaman en azından o türün bildirildiği programın program metni olduğunu izler. son not

Oluşturulmuş bir tür olan T<A₁, ..., Aₑ> için erişilebilirlik alanı, bağlanmamış genel tür T'in ve tür bağımsız değişkenleri A₁, ..., Aₑ'nin erişilebilirlik alanlarının kesişimidir.

Mprogramı içinde, T içinde bildirilen iç içe bir üye olan P'ın erişim alanı şu şekilde tanımlanır (not olarak M kendisi de bir tür olabilir):

  • M BinaryCompatOnlyAttributeile işaretlenmişse, M'ün erişilebilirlik alanı, P'ün program metni ve P'e başvuran tüm programlar için tamamen ulaşılamaz.
  • M'nin bildirilen erişilebilirliği publicise, M'nin erişilebilirlik alanı Talanıdır.
  • M’ın bildirilen erişilebilirliği protected internalise, D, P program metni ile Tdışında bildirilen ve Ptüretilen herhangi bir türün program metninin birleşimi olarak tanımlansın. M'nin erişilebilirlik etki alanı, T erişilebilirlik etki alanının Dile kesişimidir.
  • M bildirilen erişilebilirliği private protectedise, D, P ve T'ün program metinlerinin ve T'ten türetilmiş herhangi bir türün kesişimi olarak tanımlansın. M'nin erişilebilirlik etki alanı, T erişilebilirlik etki alanının Dile kesişimidir.
  • M bildirilen erişilebilirliği protectedise, D, Tprogram metni ile T'ten türetilmiş herhangi bir türdeki program metninin birleşimi olsun. M'nin erişilebilirlik etki alanı, T erişilebilirlik etki alanının Dile kesişimidir.
  • M'nin bildirilen erişilebilirliği internalise, M'nin erişilebilirlik etki alanı, T erişilebilirlik etki alanının Pprogram metniyle kesişimidir.
  • M'nin bildirilen erişilebilirliği privateise, M'nin erişilebilirlik etki alanı Tprogram metnidir.

Bu eklemelerin amacı, BinaryCompatOnlyAttribute ile işaretlenen üyelerin herhangi bir konuma tamamen erişilemez olmasını sağlamak, üye aramasına katılmamalarını ve programın geri kalanını etkileyememelerini sağlamaktır. Sonuç olarak bu, arabirim üyelerini uygulayamayacakları, birbirlerini çağıramayacakları ve geçersiz kılınamayacakları (sanal yöntemler), gizlenemeyecekleri veya uygulanamayacakları (arabirim üyeleri) anlamına gelir. Bunun çok katı olup olmadığı aşağıdaki açık soruların konusudur.

Çözülmemiş sorular

Sanal yöntemler ve geçersiz kılma

Sanal yöntem BinaryCompatOnlyolarak işaretlendiğinde ne yapacağız? Türetilmiş bir sınıftaki geçersiz kılmalar, mevcut derlemenin bir parçası olmayabilir ve kullanıcı, yalnızca dönüş türüyle farklılık gösteren ve normalde C#'da aşırı yüklemeye izin verilmeyen bir yöntemin yeni bir sürümünü tanıtmak isteyebilir. Yeniden derlemede önceki yöntemin geçersiz kılmalarına ne olur? Ayrıca BinaryCompatOnlyolarak belirtilmişse, BinaryCompatOnly üyesini geçersiz kılmalarına izin veriliyor mu?

Aynı DLL içinde kullanma

Bu teklif, BinaryCompatOnly üyelerinin şu anda derlenmekte olan derleme sırasında bile hiçbir yerde görünmediğini ifade eder. Bu çok mu katı yoksa BinaryCompatAttribute üyelerin birbirine zincirlemeleri gerekiyor mu?

Arabirim üyelerini örtük olarak uygulama

BinaryCompatOnly üyelerin arabirim üyelerini uygulayabilmesi mümkün olmalı mı? Ya da bunu yapmalarına engel olunmalıdır. Bunun için, bir kullanıcı örtük bir arabirim uygulamasını BinaryCompatOnly'e dönüştürmek istediğinde, örtük arabirim uygulaması artık özgün üyeyi göremeyeceği için, muhtemelen BinaryCompatOnly üyesinin gövdesini klonlayarak açık bir arabirim uygulaması sağlaması gerekecektir.

BinaryCompatOnly olarak işaretlenmiş arabirim üyelerini uygulama

Arabirim üyesi BinaryCompatOnlyolarak işaretlendiğinde ne yapacağız? Türün yine de bu üye için bir uygulama sağlaması gerekir; yalnızca arabirim üyelerinin BinaryCompatOnlyolarak işaretlenemediğini söylememiz gerekebilir.