Neden 'void' C # 'da genel bir tür olarak kabul edilmiyor


53

voidYapıcı olmama ve genel bir tür olarak izin verilmemesi lehinde olan tasarım kararları nelerdi ? Sonuçta bu sadece özel bir boş structve tamamen PITA'nın farklı Funcve Actiondelegelere sahip olmasını önlerdi .

(C ++, açık voiddöndürmelere izin verir voidve şablon parametresi olarak izin verir )


13
@Oded Eric Lippert'in bir hesabı olduğunu ve Programcılara katıldığını göz önünde bulundurarak, sanırım yeni yaptı.
Thomas Owens

2
@BenVoigt Tek bir kişinin bilgisini gerektirmek zorunda değildir, ancak burada tek bir doğru cevabı verebilecek (kolay bir şekilde varsayabileceğim) tek bir kişi vardır. Spesifikasyona aşina olan herkes, özellikle programlama dili tasarımı konusunda bir bilgiye sahipse, muhtemelen soruyu cevaplayabilir. Aynı zamanda konuyla ilgili ilginç bir dil tasarım / dil uygulama sorusu.
Thomas Owens

6
@BenVoigt: Neden kendi bilgini doyurmak için başka hiçbir sebep yokken, tamamen geçerli ve ilginç bir soru sormak istemezsiniz? Bir arama yaptım ve cevabı bulamadım; belki de birileri bununla ilgili bir blog yazısı okudu, belki de kararı alan kişiler soruyu cevaplamak istiyor, belki birileri bu konuda karar verenlerle sohbet etti ve soruyu kendileri sordu ve cevabı iletebildi. Bu sitede yayınlanmayı bıraktım ve SO çok fazla çünkü insanlar soruları yanıtlamaktan daha kapalı bir soru almakla ilgileniyor gibi görünüyor.

4
Burada "büyük nokta" nın soru ve cevaplarını ve özellikle de SO ile işaret edebilirim, genellikle "bu sözdizimi ne anlama geliyor?" Şeklindedir. Bu sorular neredeyse hiç kapanmıyor, çünkü herkes kurucu işaretçilerin nesnelerini oluşturması için tanımları içine çekip çıkarabilir. Dövülmüş iz dışında yatan daha ilginç sorular, bazı bilgiçlik sebeplerinden dolayı siteden mahrum kalıyor: ciddi anlamda, bir yerdeki bir veri deposunda sadece birkaç kilobayt. Çok az amaca hizmet eden keyfi olarak yorumlanmış kuralları uygulamak yerine hepimiz rahatlayabilir ve öğrenmeyi kucaklayabilir miyiz?

2
@ThomasOwens: Bu sitede SO'dan daha aktif olduğumu düşünüyorum. Bu sitede her 300 kişide yaklaşık bir soruya cevap gönderiyorum. SO'da, her 1500 kişide yaklaşık bir soruya cevap gönderiyorum. SO üzerindeki C # sorularını cevaplama.
Eric Lippert

Yanıtlar:


69

"Boşluk" ile ilgili temel problem, herhangi bir başka geri dönüş tipi ile aynı anlama gelmediğidir. "void", "eğer bu yöntem geri dönerse, o zaman hiçbir değer döndürmez" anlamına gelir. Geçersiz değil; null bir değerdir. Herhangi bir değer vermez.

Bu gerçekten tip sistemini bozuyor. Tip bir sistem, hangi işlemlerin belirli değerler üzerinde geçerli olduğu konusunda mantıklı çıkarımlar yapmak için kullanılan bir sistemdir; geçersiz bir döndürme yöntemi bir değer döndürmez, bu nedenle "bu işlem için hangi işlemler geçerli?" hiç mantıklı gelme. Geçerli veya geçersiz bir işlem olması için "bir şey" yok.

Üstelik bu, çalışma zamanını şiddetli bir şeye karıştırıyor. .NET çalışma zamanı, yığın makinesi olarak belirtilen Sanal Yürütme Sisteminin bir uygulamasıdır. Yani, işlemlerin hepsinin bir değerlendirme yığını üzerindeki etkileri bakımından karakterize edildiği sanal bir makine. (Pratikte Tabii makine yığını ve kayıtları hem bir makinede uygulanacaktır, ancak sanal yürütme sistemi sadece bir yığın varsayar.) Çağrının etkisini bir boşluk yöntemine olduğunu temeldenboş olmayan bir yönteme yapılan çağrının etkisinden farklı; geçersiz olmayan bir yöntem her zaman yığında çıkarılması gerekebilecek bir şey koyar. Bir geçersiz yöntem hiçbir zaman yığına bir şey koyar. Bu nedenle, derleyici geçersiz ve boş olmayan yöntemleri, yöntemin döndürülen değerinin dikkate alınmadığı durumlarda aynı şekilde ele alamaz; yöntem geçersiz ise, o zaman bir dönüş değeri yoktur, bu yüzden pop olmamalıdır.

Tüm bu nedenlerden dolayı, "boşluk" başlatılabilecek bir tür değildir; sahip olduğu hiçbir değer onun bütün nokta. Nesneye dönüştürülemez ve geçersiz bir geri döndürme yöntemi hiçbir zaman, hiçbir zaman, geri döndürmeyen bir yöntemle polimorfik olarak işlenemez, çünkü bunu yaparken yığını bozar!

Bu nedenle, void not ettiğiniz gibi utanç verici bir tür argümanı olarak kullanılamaz. Çok uygun olurdu.

Herhangi bir şey yerine, herhangi bir şey yerine, otomatik olarak sihirli bir singleton referans türü olan "Unit" i geri döndüren herhangi bir şey yerine getirmediği takdirde hindsight'ın yararı ile daha iyi olurdu. Daha sonra her yöntem çağrısının yığına bir şey koyduğunu , her yöntem çağrısının bir nesne türünün değişkenine atanabilecek bir şey döndürdüğünü ve tabii ki Birimin bir tür argümanı olarak kullanılabileceğini biliyordunuz. Ayrı Eylem ve Func temsilci türlerine sahip olmanıza gerek yok. Ne yazık ki, içinde bulunduğumuz dünya o değil.

Bu damardaki bazı düşünceler için bakınız:


C ++, büyülü bir singleton tipi kullanmak zorunda kalmadan onu destekliyor. Ancak bunun C ++ ile tamamen farklı bir "generics" stili kullanarak C # ile ilgisi olduğunu varsayıyorum.
Winston Ewert,

4
@WinstonEwert - C ++ 'in jenerik ürünleri desteklemediğinden, temelde farklı olan şablonlara sahip olduğundan eminim. Anladığım kadarıyla, şablonlarla birlikte derleyici global bir arama yapıyor ve tür parametrelerinizle değiştiriyor, ancak jeneriklerle, tür sistemi uygun bir tür oluşturuyor. Ayrıca, C ++ şablon hatalarının bu kadar geniş olduğunu da düşünüyorum. Doğru olmayan bir şey söylersem Eric'in beni düzelttiğine eminim
Adam Rackis

1
Tüm yapıların istif üzerinde ve sıralandıkları diğer yerlerde düzgün bir şekilde yerleştirilebilmesi için derleme zamanında yapıldığını düşünüyorum. Bu nedenle Void, 0 yığın baytının içine sonsuz miktarda argüman olarak geçilmesi uygun olmalıdır. Herhangi bir yapının dönüştürülmesi objectya da çağrılması için bir yöntem gerektiğinde (elde etmek için this) Type, bellek alanından önce (çoğu CLR uygulaması için) önceden yerleştirilmiş referans ile öbek üzerine yerleştirilir ve böylece düzgün bir şekilde ele alınabilir. Bana göre, yazım sadece bazı özelliklerle (alanlar) ayırt edilebilen bir nesneler grubudur. Voidsadece bir nesne.
ony

1
@ OlivierJacot-Descombes: Eğer voidboş bir değer tipi olsaydı, o zaman bu ifade sıfır makine kodu talimatına çevrilirdi. Kodlanmış türler için çok kullanışlı değildir Void, ancak bir türün çok sayıda genel parametreye sahip olduğu durumlarda yararlıdır, ancak bazı durumlarda bazılarına ihtiyaç duyulmaz.
supercat

2
@EricLippert: Değer tipi geri dönüş değerlerinin doğru bir şekilde ele alınması, değişken sayıda kelimelerin yığından çıkarılmasını gerektirir. Sözcük sayısının sıfır olmasına izin vermede temel bir zorluk olur mu? Arayan, alan tahsis etmekten ve bir bildirimi kabul etmekten sorumluysa, tip sistemi, geçersiz bir girişin bir anlamı olmadığını ve belki de çabaya değmeyeceği düşünüldü, ancak "temel" bir sorun görmedim; .
supercat

9

Gönderen: http://connect.microsoft.com/VisualStudio/feedback/details/94226/allow-void-to-be-parameter-of-generic-class-if-not-in-c-then-just-in- Çalışma süresi

Bu aslında tasarım gereği - geçersiz türün hiçbir örneğine izin vermiyoruz (çalışma zamanındaki diğer birçok türle birlikte). CreateInstance uygulamasını geçersiz veya boş bırakamazsınız []. Güvenlik için bu tip delikleri tıkadık.

Hayatım boyunca güvenlik boşluğunun ne kadar boş olduğunu göremiyorum, ama öyle diyor.

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.