Uzatma yöntemi ve dinamik nesne


97

Sorunumu aşağıdaki kod parçacığında özetleyeceğim.

List<int> list = new List<int>() { 5, 56, 2, 4, 63, 2 };
Console.WriteLine(list.First());

Yukarıdaki kod iyi çalışıyor.

Şimdi şunu denedim

dynamic dList = list;
 Console.WriteLine(dList.First());

ancak RuntimeBinderException alıyorum.Neden böyle?


Bu, sadece 4 gün önce sorulan bu sorunun bir kopyası gibi görünüyor stackoverflow.com/questions/5270782/…
jbtule

@jbtule Fark şu ki buradaki thisdinamik, ama buraya
inerseniz

Yanıtlar:


131

Stecya'nın cevabını genişletmek gerekirse ... genişletme yöntemleri, uzantı yöntemleri biçiminde dinamik yazımla desteklenmez , yani örnek yöntemiymiş gibi adlandırılır. Ancak bu işe yarayacaktır:

dynamic dList = list;
Console.WriteLine(Enumerable.First(dList));

Elbette bu yararlı olabilir veya olmayabilir. Dinamik yazmayı neden ve nasıl kullanmaya çalıştığınız hakkında daha fazla bilgi verebilirseniz, daha fazla yardımcı olabiliriz.


Dinamik nesne ile oynuyordum ve bu istisnayı
anladım.Bu konuda

19
@geek: Şahsen benim temel kuralım sadece dynamicgerçekten ihtiyaç duyduğunuz yerde kullanmaktır ... Temel olarak, aksi halde yansıma ile üyelere erişecekseniz , bu büyük bir işaret. Öte yandan, ölümcül bir statik yazarım - diğerleri daha az karamsar politikalar önerebilir :)
Jon Skeet

2
Bilgi türüne geri çevirmek daha okunaklı olabilir, bu çalışır: Console.WriteLine (((List <int>) dList) .First ()); Veya Console.WriteLine ((dList as List <int>) .First ()) ;.
AVee

141

Jon'un cevabını genişletmek gerekirse, bunun işe yaramamasının nedeni, normal, dinamik olmayan kod genişletme yöntemlerinin, eşleşen bir uzantı yöntemine sahip statik bir sınıf için derleyici tarafından bilinen tüm sınıfların tam aramasıyla çalışmasıdır. Arama, ad alanı yuvalanmasına ve usingher ad alanındaki kullanılabilir yönergelere göre sırayla yapılır .

Bu, dinamik bir uzantı yöntemi çağrısının doğru bir şekilde çözülmesi için DLR'nin bir şekilde çalışma zamanında kaynak kodunuzdaki tüm ad alanı yuvalarının ve usingyönergelerinin ne olduğunu bilmesi gerektiği anlamına gelir . Tüm bu bilgileri arama sitesine kodlamak için kullanışlı bir mekanizmamız yok. Böyle bir mekanizma icat etmeyi düşündük, ancak çok yüksek maliyetli olduğuna ve buna değmeyecek kadar fazla program riski ürettiğine karar verdik.


Açıklama için çok teşekkür ederim.
santosh singh

3
Uzakta böyle bir özellik var mı? Kesinlikle büyük bir değişiklik olacaktır; Şu anda RunTimeBinderExceptions'ı atan çağrılar, kaynağı yeniden derlerken aniden çalışmaya başlayacaktı. Ayrıca, böyle bir özelliğin uygulanmasıyla ilişkili herhangi bir güvenlik riski olur mu?
Ani

5
@ani: Bu özelliği uygulamayı planlıyor muyuz? Hayır. Herhangi bir güvenlik riski var mı? Ben hiçbirinin farkında değilim; aklınızda ne tür bir güvenlik riski vardı? Saldırganın kim olduğunu ve kullanıcıya ne tür bir tehdit oluşturduğunu söyleyerek başlayın.
Eric Lippert

@EricLippert, tüm dynamicnesnelerin C # 'a eşit olduğunu anladım DynamicObject, bu yüzden onları ayırt etmenin bir yolu yok ve uzantı yöntemlerini eklemenin mümkün olmamasının nedenlerinden biri, dynamicdoğru mu?
Tom Sarduy

@EricLippert, bu yanıtı biraz daha genişletmeyi ve " Parametrelerden herhangi biri dinamik olduğunda, tüm çözünürlükler çalışma zamanına ertelenir " satırları boyunca bir cümle eklemeyi düşünün . Sizin için bu önemli
parçayı SO'da

18

Çünkü First()bir yöntem değildir List. Linq Extension'da tanımlanmıştır.IEnumerable<>

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.