Öncelikle, Jon'un cevabının doğru olduğunu söylememe izin verin. Bu, şartnamenin en tüylü kısımlarından biri, Jon'a ilk önce dalmak için çok iyi.
İkincisi, şunu söyleyeyim:
Bir yöntem grubundan uyumlu bir temsilci türüne örtük bir dönüşüm var
(vurgu eklenmiştir) son derece yanıltıcı ve talihsizdir. Mads ile "uyumlu" kelimesinin buradan kaldırılması hakkında bir konuşma yapacağım.
Bunun yanıltıcı ve talihsiz olmasının nedeni, bunun bölüm 15.2, "Temsilci uyumluluğu" na sesleniyormuş gibi görünmesidir. Bölüm 15.2, yöntemler ve temsilci türleri arasındaki uyumluluk ilişkisini açıkladı , ancak bu , farklı olan yöntem gruplarının ve temsilci türlerinin dönüştürülebilirliği sorunudur .
Artık bunu ortadan kaldırdığımıza göre, şartnamenin 6.6. Bölümünü inceleyebilir ve ne elde ettiğimizi görebiliriz.
Aşırı yük çözümü yapmak için önce hangi aşırı yüklerin uygulanabilir adaylar olduğunu belirlememiz gerekir . Bir aday, tüm argümanlar örtük olarak biçimsel parametre türlerine dönüştürülebilirse uygulanabilir. Programınızın bu basitleştirilmiş sürümünü düşünün:
class Program
{
delegate void D1();
delegate string D2();
static string X() { return null; }
static void Y(D1 d1) {}
static void Y(D2 d2) {}
static void Main()
{
Y(X);
}
}
O halde satır satır geçelim.
Bir yöntem grubundan uyumlu bir temsilci türüne örtük bir dönüştürme vardır.
Burada "uyumlu" kelimesinin ne kadar talihsiz olduğunu zaten tartışmıştım. Hareketli. Y (X) üzerinde aşırı yük çözümü yaparken merak ediyoruz, yöntem grubu X D1'e dönüşüyor mu? D2'ye dönüşüyor mu?
Bir temsilci türü D ve bir yöntem grubu olarak sınıflandırılmış bir E ifadesi verildiğinde, E, parametrenin kullanımıyla oluşturulan bir bağımsız değişken listesine uygulanabilir en az bir yöntem [...] içeriyorsa, E'den D'ye örtük bir dönüştürme vardır. D'nin türleri ve değiştiricileri aşağıda açıklandığı gibi.
Çok uzak çok iyi. X, D1 veya D2'nin bağımsız değişken listelerine uygulanabilen bir yöntem içerebilir.
Bir yöntem grubu E'den bir temsilci tipi D'ye bir dönüşümün derleme zamanı uygulaması aşağıda açıklanmaktadır.
Bu satır gerçekten ilginç bir şey söylemiyor.
E'den D'ye örtük bir dönüşümün varlığının, dönüşümün derleme zamanı uygulamasının hatasız bir şekilde başarılı olacağını garanti etmediğini unutmayın.
Bu çizgi büyüleyici. Bu, var olan, ancak hataya dönüştürülebilecek örtük dönüşümler olduğu anlamına gelir! Bu tuhaf bir C # kuralıdır. Konunun dışına çıkmak için işte bir örnek:
void Q(Expression<Func<string>> f){}
string M(int x) { ... }
...
int y = 123;
Q(()=>M(y++));
İfade ağacında artış işlemi geçersizdir. Ancak, lambda hala konvertibl dönüşüm hiç kullanılırsa rağmen ifade ağacı türüne, bunun bir hata olduğunu! Buradaki ilke, daha sonra bir ifade ağacında neyin gidebileceğinin kurallarını değiştirmek isteyebileceğimizdir; bu kuralları değiştirmek , tür sistemi kurallarını değiştirmemelidir . Sizi, programlarınızı şimdi daha açık hale getirmeye zorlamak istiyoruz , böylece gelecekte daha iyi hale getirmek için ifade ağaçlarının kurallarını değiştirdiğimizde, aşırı yük çözümlemesinde kırılma değişiklikleri yapmayız .
Her neyse, bu, bu tür tuhaf kuralların başka bir örneğidir. Aşırı yük çözümü amacıyla bir dönüştürme mevcut olabilir, ancak gerçekten kullanılması bir hata olabilir. Gerçi aslında, burada bulunduğumuz durum tam olarak bu değil.
Hareketli:
E (A) biçimindeki bir yöntem çağrısına karşılık gelen tek bir yöntem M seçilir [...] Argüman listesi A, her biri biçimselde karşılık gelen parametrenin bir değişkeni [...] olarak sınıflandırılan bir ifade listesidir. -D'nin parametre listesi
TAMAM. D1'e göre X üzerinde aşırı yük çözümü yapıyoruz. D1'in biçimsel parametre listesi boş, bu yüzden X () ve joy üzerinde aşırı yük çözümlemesi yapıyoruz, çalışan bir "string X ()" yöntemi buluyoruz. Benzer şekilde, D2'nin resmi parametre listesi boştur. Yine, "string X ()" in burada da çalışan bir yöntem olduğunu görüyoruz.
Buradaki ilke, yöntem grubu dönüştürülebilirliğinin belirlenmesinin aşırı yük çözümlemesini kullanan bir yöntem grubundan bir yöntem seçmeyi gerektirmesidir ve aşırı yük çözümlemesi dönüş türlerini dikkate almaz .
Algoritma [...] bir hata üretirse, derleme zamanı hatası oluşur. Aksi takdirde, algoritma, D ile aynı sayıda parametreye sahip tek bir en iyi yöntem M üretir ve dönüşümün var olduğu kabul edilir.
X yöntem grubunda yalnızca bir yöntem vardır, bu nedenle en iyisi olmalıdır. X'ten D1'e ve X'ten D2'ye bir dönüşümün var olduğunu başarıyla kanıtladık .
Şimdi, bu satır alakalı mı?
Seçilen yöntem M, temsilci tipi D ile uyumlu olmalıdır, aksi takdirde bir derleme zamanı hatası oluşur.
Aslında hayır, bu programda değil. Bu hattı harekete geçirecek kadar ileri gidemeyiz Çünkü unutmayın, burada yaptığımız şey Y (X) üzerinde aşırı yük çözümü yapmaya çalışmaktır. Y (D1) ve Y (D2) olmak üzere iki adayımız var. Her ikisi de uygulanabilir. Hangisi daha iyi ? Spesifikasyonun hiçbir yerinde bu iki olası dönüşüm arasındaki daha iyi tanımlayamıyoruz .
Şimdi, kesinlikle geçerli bir dönüşümün, bir hata üretenden daha iyi olduğu tartışılabilir. Bu, daha sonra, bu durumda, aşırı yük çözümlemesinin dönüş türlerini dikkate aldığını, ki bu da kaçınmak istediğimiz bir şeydir. O zaman soru, hangi ilkenin daha iyi olduğudur: (1) aşırı yük çözümlemesinin dönüş türlerini dikkate almadığı değişmezi koruyun veya (2) çalışmayacağını bildiğimiz bir dönüşüm üzerinde çalışacağını bildiğimiz bir dönüşümü seçmeye çalışın mı?
Bu bir yargılama çağrısıdır. İle lambdas , biz yapmak bölümünde 7.4.3.3 yılında, dönüşümler bu tür dönüş türünü göz önünde bulundurun:
E, anonim bir işlevdir, T1 ve T2, aynı parametre listelerine sahip temsilci türleri veya ifade ağacı türleridir, bu parametre listesi bağlamında E için çıkarılan bir dönüş türü X vardır ve aşağıdaki tutulanlardan biri:
T1, Y1 dönüş türüne sahiptir ve T2, Y2 dönüş türüne sahiptir ve X'ten Y1'e dönüşüm, X'ten Y2'ye dönüşümden daha iyidir
T1'in dönüş türü Y vardır ve T2 geçersizdir
Metot grubu dönüşümlerinin ve lambda dönüşümlerinin bu açıdan tutarsız olması talihsiz bir durumdur. Ancak onunla yaşayabilirim.
Her neyse, X'den D1'e veya X'den D2'ye hangi dönüşümün daha iyi olduğunu belirleyecek "daha iyi" bir kuralımız yok. Bu nedenle Y (X) çözünürlüğünde bir belirsizlik hatası veriyoruz.