C # dinamik türlerini kullanmanın eksiklikleri


14

Son zamanlarda C # dinamik türleri üzerinde daha fazla çalışıyorum . Kod derlendiğinde anladığım bazı örneklerde, yeniden derlenmesi gerekmez, ancak doğrudan yürütülebilir.

Anahtar kelime tarafından sağlanan veri türünü gerçekten değiştirmek için esnekliğin büyük bir avantaj olduğunu düşünüyorum .

Soru,

Geliştiricilerin uygulamaya başlamadan önce bilmesi gereken çalışma zamanı istisnaları atan yanlış dinamik yöntem çağrıları dışında herhangi bir eksiklik var mı ?


3
C # 3'te, her zaman objectdoğrudan veya doğrudan dökümlerin bir kod kokusu olduğunu düşündüm . Neredeyse her durumda, ben veya ekibimden birinin bu işlevsellik için uygun bir arayüz tasarlamadığı anlamına geliyordu. Şimdi C # 4'ü kullansaydım, kullanım konusunda dynamicda aynı şekilde hissedeceğimi tahmin ediyorum . Her şeyi dinamik yaparsanız bunun durumunu görebiliyordum, ancak bu durumda ilk etapta dinamik bir dil seçmiş olabilirsiniz. * 8 ')
Mark Booth

Perspektif için @MarkBooth +1. O zaman C # kullanarak çekirdek uygulamanın, 4.0'da dinamik türlerin kullanılmasına rağmen güçlü bir şekilde yazıldığını söylemek güvenli mi?
Karthik Sreenivasan

dynamicC # 'da kullanmak , ihtiyacınız olan tek şey kodunuzun küçük bir kısmı için dinamik bir yazı yazmaksa IronPython'a bırakmanız gerekmediği anlamına gelir. Bir ifade değerlendirici için, bir ifadenin dynamicişlenenlerini ve değerlendirmenin sonuçlarını temsil etmek için büyük bir başarı elde ettim .
Ed James

@EdJames - Bu büyük bir kullanımı gibi geliyor dynamic, artı keşke .Net ile geliştirirken IronPython hakkında bilseydim - çok daha kolay yapmaya çalıştığımız bazı şeyler yapmış olabilir .
Mark Booth

Yanıtlar:


16

Ana eksiklik, C # 'ın temel özelliklerinden (mutlaka avantajları değil) birini atmanızdır - statik olarak yazılmıştır (ve çoğu parça için güvenli).

Dinamik yazmayla ilgili sorun genellikle derleme sırasında ortaya çıkacak hataları gizlemesidir. Böyle bir hata daha sonra sadece çalışma zamanında tezahür eder, bu da elbette tespit edilmesini çok daha zorlaştırır.

IMO'nun dinamik yazmayı kullanmak için IMO'nun çok az nedeni vardır, bunlardan en önemlisi dinamik olarak yazılan dillerle işbirliği yapmaktır (bu, dinamik olarak ilk başta kullanılmasının nedeni AFAIK'dir).

Tamamen dinamik olarak yazılan programlama yapmak istiyorsanız, dinamik olacak şekilde tasarlanmış bir dile bakmalısınız, dinamik olmak için C # kesmek değil. Net kütüphanelerini kullanmak istiyorsanız örneğin IronPython kullanabilirsiniz.


IronPython için +1. Bu, bunun uzun vadede bakım sorunlarına yol açabileceği anlamına gelir.
Karthik Sreenivasan

6
dynamicSize veren en büyük şey, herhangi bir yansıma hilesi olmadan bir nesneyi gerçek türüne yükseltebilmesidir. Örneğin eğer Base foo = new Derived();ve orada iki aşırı yüklü yöntemleri vardı Moo(Base x)ve Moo(Derived x)daha sonra Moo(foo)aramaları Moo(Base x), ancak Moo((dynamic)foo)aramalar Moo(Derived x). Bu, Ziyaretçi deseninin çok zarif bir şekilde uygulanmasına yol açar: code.logos.com/blog/2010/03/… ve genel olarak çok güçlü bir tekniktir.

@TheMouthofaCow Nice, kesinlikle dinamik için de birkaç "meşru" kullanım var, ancak bunlar arasında çok az ve çok uzak (ve kesinlikle böyle bir şey denemeden önce ne yaptığınızı bilmelisiniz).
Matěj Zábský

@TheMouthofaCow Görece yeni bir tasarım deseni (Ziyaretçi Deseni). Teşekkürler.
Karthik Sreenivasan

1
Evet, oldukça havalı. Geçen hafta bağımsız olarak ortaya çıktı, bu yüzden C # cephaneliğine kabul edilen kabul edilmiş bir fikir olduğunu görmek güzeldi.

9

Ne tür eksiklikler aradığınızdan emin değilim, ancak statik yazımla çalışan özellikler hakkında bilmek istiyorsanız, ancak bununla birlikte değil dynamic, az şey var:

  1. Uzantı yöntemleri işe yaramıyor. Bu muhtemelen en büyüğü. Varsa dynamic collection, gibi kodu kullanamazsınız collection.Distinct(). Bunun nedeni, kullanılabilir genişletme yöntemlerinin ad alanlarına bağlı olması usingve DLR'nin bunları bilmesinin bir yolu olmamasıdır.

    Normal statik yöntemi sanki bir çözüm olarak, ya yöntemi çağırabilirsiniz: Enumerable.Distinct(collection). Veya koleksiyonun türünü benzer bir şekilde değiştirebilirsiniz IEnumerable<dynamic>.

  2. foreachgerektirir IEnumerable. Normal C # ' foreachda desen tabanlıdır. Yani, belirli bir arabirim gerektirmez, sadece GetEnumerator()uygun nesneyi döndüren bir yöntemdir. foreachÜzerinde kullanırsanız dynamic, uygulanması IEnumerablegerekir. Ancak bu davranışın nedeni C # 1.0'ın jenerik içermemesi nedeniyle, bu "eksiklik" hemen hemen ilgisizdir.


Uzantılar için +1 yöntemi. Bu aynı zamanda GroupBy () gibi diğer LINQ sorgu işleçleri için de geçerli mi?
Karthik Sreenivasan

2
@Karthik: Evet öyle. Bence uzatma yöntemleri derleme zamanı sözdizimsel şeker, bu yüzden çözülmemesi gerçeği.

@TheMouthofaCow +1 - Açıklama için teşekkürler.
Karthik Sreenivasan

1
Uzantı yöntemlerine katılıyorum, yani dinamik çalışma sırasında uzantı yöntemlerini nasıl bulamıyor ancak açıkladığınız dinamik koleksiyonu izleyemedim.
Karthik Sreenivasan

7

.Net dosyasındaki dinamik türlerle (dinamik olarak bildirilen değişkenler değil) sorun, statik türler için çok fazla işlevselliğe sahip olmamalarıdır.

  • yansıma yok (üyeler üzerinde yineleme yapabilirsiniz, ancak çok fazla değil)
  • meta veri yok (dinamik veri sitelerinde / mvc'de doğrulamanız gider)
  • derleme zamanında kesinlikle kontrol yok (yazım hataları yakalanmaz)
  • Bu güçlü bir özellik olduğundan, noobs kötüye kullanma / kötüye kullanma / yanlış anlama eğilimi gösterebilir
  • dinamik türlerle yazılan kodun bakımı zor ve yeniden düzenlenmesi zor
  • ördek yazması ve diğer özellikleri nedeniyle gurular başkalarına okunamayan kodlar yazabilir

Ne yaptığınızı bilmiyorsanız, dinamik türlerle kod yazmayın.


6

Çünkü dynamicsadece işaretlenmiş bir objectdeğer türleri kutuları.

Bu performans sonuçları olabilir, ancak yine de performans kritik kod statik yazmayı kullanmak istiyorum, bu muhtemelen pratikte bir sorun değil.

Bu boks aynı zamanda değişken değer tiplerini de etkiler. Bunları ile dynamicdeğiştirirseniz, yalnızca kutulu kopyayı değiştirirsiniz. Ancak ilk etapta değişken değer türlerini kullanmamanız gerektiğinden, bu da büyük bir sorun değildir.


+1 Kesinlikle katılıyorum. Statik yazım, performans açısından kritik kod için en iyi yaklaşım olacaktır.
Karthik Sreenivasan
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.