C # veya .Net özellikleri geriye dönük uyumluluk gerekmediğini varsayarak kesmek için? [kapalı]


18

Herhangi bir ürün veya çerçeve gelişir. Temel olarak kullanıcılarının ihtiyaçlarını yakalamak, yeni bilgi işlem güçlerinden yararlanmak ve daha iyi hale getirmek için yapılır. Bazen birincil tasarım hedefi ürünle de değişir. C # veya .net çerçevesi bir istisna değildir. Gördüğümüz gibi, günümüzün 4. versiyonu birincisine kıyasla çok farklı. Ancak şey, bu evrimsel geriye dönük uyumluluğa barikat olarak gelir.

Çerçevelerin / ürünlerin çoğunda geriye dönük uyumluluğu desteklemeye gerek olmasaydı özellikler kesilirdi. Size göre, C # /. Net bu özellikleri nelerdir?

Lütfen her cevap için bir özellik belirtin.



4
Soru, kılavuzlara göre açıkça yapıcı değil ve harika cevaplara dayalı olarak açıkça yapıcı. Yeniden açmak için oylama.
psr

1
Yazık kapalı, hala Eric burada cevaplamak yerine bunu blog yazacak?
jk.

Yanıtlar:


35

Anonim yöntemler . Herkes C # 2.0 için seçilen anonim yöntem sözdizimi, C # 3.0 için eklenen lambda sözdizimine göre tıknaz ve tıknaz olduğunu kabul eder. Aynı şeyi yapmak için neredeyse özdeş iki sözdizimine sahip olmak çok talihsiz bir durumdur.


1
Anlaşıldı, anonim yöntemler lambdalarımız olmadığında harikaydı ... şimdi sadece gereksizler.
Michael Brown

9
Anonim yöntemlerin lambda ifadelerinden çok daha iyi bir özelliği vardır .... onların mükemmel adı !!
explorest

1
Bu noktada, C # anonim bir yöntem için sözdizimi bile hatırlamıyorum. Bir tuhaf nedenden dolayı lambda yerine bir tane kullanmam gerekiyorsa onu aramam gerekirdi.
Kyralessa

33

Jenerik olmayan koleksiyonlardan kurtulurdum. Onlar bir iğrenç ... ve linq kullandığım ve böyle bir şey yapmak zorunda olduğum çok fazla vaka var

var customObjects = container.CustomObjects.Cast<CustomObject>();

Bunu her yaptığımda, ruhumun küçük bir kısmı ölür.


Bu çok harika.

1
Tüm .NET portları Generics'i desteklemez. .NET Micro bir örnektir. CustomObjects hiçbir zaman bu platforma taşınmazsa geçerli olmayabilir.
goodguys_activate

2
Ruha sahip olmamanın avantajı budur.
CaffGeek

29

tür olarak geçersizdir . Neden "geçersiz" bir tür? Hiçbir örneği yoktur, değeri yoktur, genel tür argümanı, resmi parametre türü, yerel tür, alan türü veya özellik türü olarak kullanamazsınız. Bir tür olarak hiçbir anlamı yoktur; daha ziyade, bir yöntem çağrısının sanal makine yığını üzerinde ne gibi bir etkisi olduğu bir gerçektir . Ancak sanal makine sadece budur: sanal bir makine. Gerçek makine döndürülen değeri bir kayıt defterine koyar (genellikle x86'da EAX) ve yığını hiç etkilemez! Bir tür olarak geçersizlik sadece kötü bir fikirdir.

Daha kötüsü: bir işaretçi türünde kullanıldığında, dönüş türü olarak kullanıldığından tamamen farklı birvoid* şey ifade eder. Şimdi "bilinmeyen tipte bir depolama yerine bir işaretçi" anlamına gelir. Bu, "herhangi bir değer döndürmeyen bir yöntem" anlamıyla hiçbir ilgisi yoktur.

void*İşaretçi türü olarak değiştirebilirsiniz IntPtr. (Ve void**ile IntPtr*vb.) Biz, "Unit", tek bir değer, yani null adlı olan bir tür olan bir dönüş türü olarak void yerini alabilir. CLR'nin bir uygulaması daha sonra, bir birim tipi işlev çağrısının "döndürülen" null değerinin güvenli bir şekilde göz ardı edilebileceğini bilerek kayıt veya yığın kullanımını uygun şekilde optimize edebileceğine karar verebilir.

Böyle bir dünyada artık ayrı Func<A, R>ve Action<T>delegelere ihtiyacınız yok . Action<T>sadece Func<T, Unit>.


4
... ve Tasksadece bir Task<Unit>. Zaman uyumsuz CTP'nin kütüphane parçalarını yeniden uygulamak beni gerçekten bunun için diledi ...
Jon Skeet

24

Boş ifade; . Hata eğilimli, neredeyse her zaman bir yazım hatasıdır ve size zaten ifade edilmeyen hiçbir ek anlam vermez {}.


7
64 bit JIT </snark> altındaki büyük performans cezasından bahsetmiyoruz bile.
Jesse C. Slicer

7
Boş bir ifadenin performans cezası var mı? Neden?
quentin-starin

22

Referans tip dizilerde güvensiz kovaryans . Typesafe kovaryans açıkken IEnumerable<T>, dizi kovaryans ihtiyacının en azından bir kısmı ortadan kalkmıştır. (Kovaryant salt okunur bir liste arayüzümüz olsaydı, buna hiç ihtiyacımız olmazdı.)


Soru başlığını gördüğümde kesinlikle yazacaktım - beni dövüyordun :(
Chris Smith

1
Bir kovaryant dizi referansı alma ve ondan okunan dizi referanslarına güvenli bir şekilde yazma yeteneği yararlıdır. Gibi Eğer IList<T>miras IReadableList<out T>ve olmayan jenerik IPemutable, bu sıralama gibi şeyler destekleyebilir, ancak diziler daha kolay bunu destekleyecek.
supercat

14

Tekli artı operatör . Tüm zamanların en az kullanışlı operatörü. Geriye dönük uyumluluk için tutmak zorunda olmasaydık, bir kalp atışında çıkarırdım. Kim bu şeyi kullanıyor?

(Açıklama: tekli artı işareti +xÖn artırma operatör değildir ++xdeğil, postincrement operatör x++olup ikili ek operatör x+y).


1
için (int i = 0; i <tavan; i ++)
Michael Brown

13
O Ön artırma ve postincrement operatörler söz etmiyordu: o tekli artı, bir dizi olumsuz işaretinin tersi bahsediyor: +1 == 1. Hayır-op yakın oldukça lanet.
Jesse C. Slicer

8
Bu sadece makine tarafından okunabilir çıkışı üzerindeki etkisi hakkında, insanlar için kod görünmesini sağlayabilir değil: if(a == +1 || a == -1){...}.
Thomas Bratt

5
@ShuggyCoUK: Bu konuda özellikle garip olan şey, yüklenebilir olmasıdır . Çünkü bu çok oluyor. Bilirsiniz, nasıl JavaScript yazıyorsunuz ve dostum, JS'nin kullanıcı tanımlı tekli artı C # gibi operatör semantiği yapmama izin vermesini diliyorum .
Eric Lippert

2
@Eric Aşırı yüklenebilir olduğunu fark etmedim. Vay be sen-ebil yapmak ile bazı kötü şaşkınlık :)
ShuggyCoUk

12

Sayısal değişmezleri varsayılan olarak double

Çoğu uygulaması için, decimalyine de daha uygundur ... veya belki de bir varsayılan fikri kaldırmak ve geliştiriciyi gerçekten seçim yapmaya zorlamak daha iyi olur .

(De bazı başka şeyler için uygun olacağını "varsayılan kaldırmak" Bu. Örneğin, ben sınıflar varsayılan olarak kapalı gerektiğini herkesi ikna etmeye çalışıyor vazgeçtiği, ama onlar gerektiğini insanları ikna etmek kolay şüpheli ettik düşünüyorum yaklaşık yeni sınıflarının mühürlenmesi gerekip gerekmediği ve açıkça belirtilmesi).


Belki de tam olarak bir çift / şamandıra olarak temsil edilemeyen bir değeri ima eden değişmezleri tanımlamak için yalın ...
ShuggyCoUk

Java'ya girdiyse - bunları Joshua Bloch'un kutsal metinlerine yönlendirin "miras için tasarım veya belge veya başka bir şekilde yasaklayın" martinfowler.com/bliki/DesignedInheritance.html IIRC kotlin varsayılan olarak sınıfları mühürler, böylece endüstri bu açıdan daha iyi bir yön.
Elazar Leibovich

Sınıflar neden mühürlenmeli?
James

@ James: Josh'un verdiği nedenlerden dolayı. Kalıtımın makul ve tutarlı bir şekilde yapılmasını sağlayan bir sınıf tasarlamak zaman alır - ve bunu kalıtımın nasıl kullanılacağını bilmeden yapmak daha da kötüdür.
Jon Skeet

1
@Pacerier: Örneğin değişmezliği düşünün. Mühürlü olmayan bir sınıf değişmez olduğunu iddia edemez, çünkü alt sınıflar değişebilirlik sağlayabilir.
Jon Skeet

7

Bu, bir özellikten daha çok bir kılavuzdur, ancak bence bu önemli çünkü kanonik ve en iyi çözüm olarak insanların zihninde zaten çok fazla kökleşmiş:

Resmi desen uygulamak IDisposable.

Bu hantal ve daha iyi yollar var .


6

Çeşitli zamanlayıcı sınıfları arasında büyük farklılıklar olduğunu biliyorum . Ama yine de bir veya iki tanesinden kurtulamadık mı?


4

Yöntem ve türleri Arrayve List<T>bu örneğin, Linq ile demode olmadan:

  • Array.TrueForAll ile değiştirilebilir Enumerable.All
  • Array.FindAll ile değiştirilebilir Enumerable.Where
  • List<T>.ConvertAll ile değiştirilebilir Enumerable.Select
  • Predicate<T> ile değiştirilebilir Func<T, bool>
  • Converter<T,R> ile değiştirilebilir Func<T, R>
  • IComparer<T> gerçekten bir temsilci olmalı Func<T, T, int>

3
Seviyorum Predicate<T>çünkü işlevin nasıl kullanıldığı konusundaki niyetini yakalar ve küçük bir yazım tasarrufu sağlar.
Zebi

2

Jenerik Olmayan Delegeler Jenerik olmayan koleksiyonlar gibi jenerik olmayan delegeler de artık Func ve Action serisine sahip olduğumuz için işe yaramaz. Ve üç parametrede varyantları keserdim. Üçten fazla parametreniz varsa, bir yapı oluşturun ve bunu tek parametre olarak kullanın. Olay işleme için belirli bir delege bildirmek çok KURU değil.


3
Action veya Func ile ref int alan bir yönteme nasıl bir temsilci tanımlarsınız? Func ile bir birleştiriciyi nasıl tanımlarsınız ? Yani, "DD (DD) delegesi" demenin bir yolu yoktur; Func ile.
Eric Lippert

2
hmmm ... Düzeltilmiş duruyorum. Bu yüzden yetenekli ellerinde kullandığım araçları yaratma işini bırakıyorum;)
Michael Brown

@EricLippert: CLR büyüsü aracılığıyla "her" arity delege ve değer / referans parametrelerinin birleşimini içeren özel bir delege sınıfı görmek istiyorum [sihirli sınıfta uygun biçimde biçimlendirilmiş bir adla bir delege aramak yazın] ve uygun imzaya sahip tüm delegelerin bundan devralmasını sağlayın. Belirli bir temsilci isteyen kod yine de tam bir tür gerektirir, ancak belirli bir imza isteyen kod sihirli adı kullanabilir.
supercat

-1

asmx Web Hizmetleri

Bence günümüzde WCF ile oldukça eski.


6
Evet, ama bazen grok yapmak çok daha kolay. . .
Wyatt Barnett

-2

Winforms
İki masaüstü platformu arasında gezinmek zorunda değilsiniz. WPF, işlerin gittiği yerdir, bu nedenle platform düzeyinde yedekliliğe sahip olmak sinir bozucu.


Winforms,
WPF'den

Küçük bir masaüstü uygulamasını hacklemeniz gerektiğinde, WPF büyük bir abartıdır.
Kyralessa

WPF arasında WinRT lehine oldukça eskimiş görünüyor. Ancak bana göre Winforms iş geliştirme konusunda WPF'den daha canlı görünüyor. Ayrıca bkz stackoverflow.com/questions/913417/…
Doc Brown
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.