SORU
13 Ocak 2010, ÇARŞAMBA


İşlev< derleyici Belirsiz çağırma hatası - anonim metod ve Yöntem grup;> ya da Eylem

(Ya da lambda sözdizimi) bir işlev çağırmak için yöntem grup sözdizimi yerine anonim yöntemler kullanmak istediğim bir senaryo var.

İşlevi iki aşırı, Action, Diğer sürer Func<string> alır.

Mutlu iki aşırı anonim yöntemler (veya lambda sözdizimi) kullanarak, ama bir derleyici hatası diyebilirimBelirsiz çağırmayöntem grup sözdizimi kullanıyorum. Action Func<string>, açık çevrim tarafından geçici çözüm olabilir ama bu gerekli olması gerektiğini düşünmüyor.

Herkes açık atmalarını gerekli neden açıklayabilir.

Aşağıdaki kod örneği.

class Program
{
    static void Main(string[] args)
    {
        ClassWithSimpleMethods classWithSimpleMethods = new ClassWithSimpleMethods();
        ClassWithDelegateMethods classWithDelegateMethods = new ClassWithDelegateMethods();

        // These both compile (lambda syntax)
        classWithDelegateMethods.Method(() => classWithSimpleMethods.GetString());
        classWithDelegateMethods.Method(() => classWithSimpleMethods.DoNothing());

        // These also compile (method group with explicit cast)
        classWithDelegateMethods.Method((Func<string>)classWithSimpleMethods.GetString);
        classWithDelegateMethods.Method((Action)classWithSimpleMethods.DoNothing);

        // These both error with "Ambiguous invocation" (method group)
        classWithDelegateMethods.Method(classWithSimpleMethods.GetString);
        classWithDelegateMethods.Method(classWithSimpleMethods.DoNothing);
    }
}

class ClassWithDelegateMethods
{
    public void Method(Func<string> func) { /* do something */ }
    public void Method(Action action) { /* do something */ }
}

class ClassWithSimpleMethods
{
    public string GetString() { return ""; }
    public void DoNothing() { }
}

CEVAP
13 Ocak 2010, ÇARŞAMBA


Öncelikle, bana Jon cevabı doğru olduğunu söylememe izin verin. Bu spec en ağır parçalar, ilk baş dalmak için. Jon çok iyi biridir.

İkincisi, bana bu hattı diyelim:

Örtülü bir dönüştürme yöntemi bir grup varuyumlu temsilci türü

(vurgu eklenmiştir) derinden yanıltıcı ve talihsiz. "Uyumlu" burada kaldırıldı. kelime alma hakkında Mads ile konuşacağım

Bu yanıltıcı ve talihsiz olmasının nedeni bu bölüm sesleniyorum gibi görünüyor, çünkü 15,2 ve, "Temsilci uyumluluk". Bölüm 15,2 ve uyumluluk arasındaki ilişkiyi tarifyöntem ve temsilci türleriama bu karşılığının olduğu ilan edilen bir soruyöntem grupları ve temsilci türlerifarklı olan.,

Yoldan geldikten sonra, spec bölüm 6.6 ile yürüyebiliriz ve nasıl olduğunu görelim.

Aşırı çözümleme yapacak olan ilk belirlememiz gerekiyorilgili adaylar. Bir aday eğer tüm değişkenler formal parametre tür örtük olarak dönüştürülebilir ise geçerlidir. Program: bu basitleştirilmiş versiyonu 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);
    }
}

Hadi içinden satır satır.

Örtülü bir dönüştürme uyumlu bir temsilci türü için yöntem bir grup var.

Zaten "uyumlu" talihsiz işte. nasıl konuştum Devam ediyorum. Y(X) aşırı çözümleme yaparken merak ediyoruz, yöntemi grup X D1 dönüştürmek yapar? D2 dönüştürmek mi?

Bir temsilci türü verilen D ve bir ifade olarak sınıflandırılan E yöntem grup, bir örtük dönüştürme eğer E varsa D, E var en azından geçerli bir yöntem [...] bir argüman listesi kullanarak inşa parametre türleri ve değiştiriciler Aşağıdaki açıklandığı gibi D,.

Şimdiye kadar çok iyi. X D1 veya D2 tartışma listeleri ile ilgili bir yöntem içerebilir.

Bir temsilci türü için yöntem grup E bir dönüşüm derleme zamanı uygulama Ge aşağıdaki şekilde tanımlanmıştır.

Bu hat gerçekten ilginç bir şey söylemiyor.

D E örtülü bir dönüştürme varlığını dönüşüm derleme zamanı uygulama hata olmadan başarılı olacağına dair garanti etmez unutmayın.

Bu hat büyüleyici. Var olan, ama hataları dönüştü söz konusu örtülü dönüşüm var demektir! Bu C tuhaf bir kuraldır#. Bir an konuyu dağıtmak için, burada bir örnek:

void Q(Expression<Func<string>> f){}
string M(int x) { ... }
...
int y = 123;
Q(()=>M(y  ));

Artırma işlemi ifade ağaç yasal değildir. Ancak, lambda haladönüştürülebilireğer dönüşüm hiç kullanılırsa bile ifade ağaç türü için, bir hatadır! Prensip burada ifade ağaç daha sonra ne kuralları değiştirmek isteyebiliriz; bu kuralları değiştirme değiştirmemelisinizyazın sistemi kuralları. Sizin programlarınız belirli hale getirmek için zorlamak istiyoruzşimdionları daha iyi hale geleceğini ifade ağaçları, kuralları değiştiririz , böyleceaşırı yükleme çözünürlüğü En son değişiklikleri tanıtmak istemiyoruz.

Her neyse, bu tuhaf kuralı bu tür başka bir örnektir. Bir dönüşüm aşırı çözümleme amacıyla var, ama aslında kullanmak için bir hata olabilir. Aslında rağmen, o tam olarak burada durum değildir.

Devam:

Bir tek yöntem M, seçili ilgili bir yöntem çağırma şeklinde E(A) [...] bağımsız değişken listesi Bir listesidir ifadeler, her gizli olarak bir değişken [...] ilgili parametre formal-parametre-listesi D

TAMAM. D1 saygı ile X üzerinde aşırı çözümleme yapıyoruz. D1 biçimsel parametre listesi boş, X üzerinde aşırı çözümleme yapıyoruz ve bu yüzden sevinç, bir yöntem bulduk "string X()" bu işe yarar. Benzer şekilde, D2 biçimsel parametre listesi boş. Yine, "string X()" burada çalışan bir yöntemdir.

Burada ilkebelirleme yöntemi grup karşılığının olduğu ilan yöntemi gruptan bir çözüm yöntemi aşırı kullanarak seçilmesi gerekirveaşırı çözümleme dönüş türleri dikkate almaz.

Algoritma [...] eğer bir hata üretir, bir derleme zamanı hatası oluşur. Aksi halde algoritma en iyi yöntem, tek bir M D ve dönüşüm var kabul edilir gibi parametreleri aynı sayıda olması üretiyor.

Yöntem grup X tek bir yöntem yoktur, en iyisi olmalı. Başarılı bir dönüşüm olduğunu kanıtladıkvarD2 X D1 ve X.

Şimdi, bu hat ile ilgili?

Seçilen yöntem M temsilci türü D, ya da aksi ile uyumlu olması gerekir, bir derleme zamanı hatası oluşur.

Aslında, Hayır, bu programda değil. Biz asla bu hat açma kadarıyla. Burada ne yaptığımızı hatırlıyor musun, Y(X) aşırı çözümleme yapmaya çalışıyor çünkü. Y(D1) ve Y(D2) iki adayımız var. Her ikisi de geçerlidir.daha iyi?Hiçbir özellikleri muyuz bu iki olası dönüşüm arasında betterness tarif.

Şimdi, kesinlikle geçerli bir dönüştürme, bir hata üretir, eskisinden daha iyi olduğunu söyleyebiliriz. O zaman etkili bir şekilde aşırı çözümleme kaçınmak istediğimiz şey bu, dönüş türleri, düşünün ki bu durumda diyorum. O zaman soru şu hangi ilkesidir daha iyi: (1) bakım değişmeyen bu aşırı çözüm değil düşünün dönüş türleri, veya (2) almaya çalışın dönüşüm bilecek bir iş olduğunu biliyoruz değil mi?

Aceleyle alınmış bir karar. İleLambdabizyapınbölüm 7.4.3.3 dönüşümleri, bu sıralar dönüş türü düşünün

E bir anonim işlev, T1 ve T2. temsilci türleri veya ifade ağacı türleri aynı parametre listeleri ile, olayla dönüş türü bir X E var Bu parametre listesi kapsamında ve aşağıdaki tutan biri

  • Yazın Y1 T1 ve T2 dönüş türü Y2 ve dönüşümü olan bir dönüş var Y1 X daha iyi. Y2 X-dönüşüm

  • T1 dönüş türü bir Y var, ve T2 boşluk veriyor

Yöntem grup dönüşüm ve lambda dönüşüm bu açıdan tutarsız büyük bir talihsizliktir. Ancak, bununla yaşayabilirim.

Neyse, hayır "" daha iyi olduğunu belirlemek için kural, X ya da X D1 D2. betterness var Bu nedenle Y çözünürlüğü(X) üzerinde belirsizlik bir hata veriyoruz.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • chrmoe

    chrmoe

    7 Kasım 2006
  • Lin Steven

    Lin Steven

    17 EKİM 2006
  • Tube Time

    Tube Time

    14 Mayıs 2013