.NET çerçevesinin neden birinci sınıf tür olarak sınıf kavramı yoktur?


20

C # ve .NET çerçevesinin, Delphi'nin baş geliştiricisi Anders Hejlsberg tarafından tasarlanan "Delphi'nin Java gibi hissetmek için yeniden yazıldığı" olarak başladığı tarihe aşina olanlar tarafından iyi bilinir. O zamandan beri işler biraz farklılaştı, ancak benzerliklerin başında o kadar açıktı ki , .NET'in aslında Borland'ın ürünü olduğu konusunda ciddi bir spekülasyon bile vardı .

Ama son zamanlarda bazı .NET şeylerine bakıyordum ve Delphi'nin en ilginç ve kullanışlı özelliklerinden biri tamamen eksik görünüyor: birinci sınıf bir veri türü olarak sınıf kavramı. Bunu bilmeyenler TClassiçin Typetür, .NET'teki türe benzer bir sınıfa yapılan başvuruyu temsil eder . Ancak .NET'in Typeyansıma için kullandığı Delphi TClass, dilin çok önemli bir yerleşik parçası olarak kullanır . Sınıf alt türü değişkenleri ve sanal sınıf yöntemleri gibi, onsuz varolmayan ve varolmayan çeşitli yararlı deyimlere izin verir.

Her OO dili, farklı sınıfların bir yöntemin aynı temel kavramını farklı şekillerde uyguladığı sanal yöntemlere sahiptir ve daha sonra doğru yöntem çağrıldığı nesne örneğinin gerçek türüne göre çalışma zamanında çağrılır. Delphi bu kavramı sınıflara genişletir: belirli bir sınıf alt türü olarak tanımlanmış bir TClass başvurunuz varsa (yani class of TMyClass, değişkenin TMyClasssınıf kapsamı sanal yöntemleri eklenmiş olan, sınıfsal sanal yöntemlere sahip olan mirasçıdan miras alan herhangi bir sınıf başvurusunu kabul edebileceği anlamına gelir ) sınıfın gerçek türü kullanılarak örneksiz çağrılabilir. Bu kalıbı kuruculara uygulamak, örneğin bir Fabrika uygulamasını önemsiz hale getirir.

.NET'te eşdeğer bir şey yok gibi görünüyor. Sınıf referansları (ve özellikle sanal kurucular ve diğer sanal sınıf yöntemleri!) Kadar kullanışlı olan, neden dışarıda bırakıldıkları hakkında bir şey söyledi mi?

Özel Örnekler

Form Diziselleştirme

Delphi VCL, formları DFMbir bileşen hiyerarşisini tanımlamak için bir DSL biçiminde kaydeder . Form okuyucu DFM verilerini ayrıştırdığında, şu şekilde açıklanan nesnelerle çalışır:

object Name: ClassName
   property = value
   property = value
   ...
   object SubObjectName: ClassName
      ...
   end
end

Burada ilginç olan ClassNamekısım. Her bileşen sınıfı TClass, initializationzaman içinde bileşen akış sistemine kaydedilir (yalnızca biraz farklı olan statik kurucuların başlangıçta hemen gerçekleşmesi garanti edilir.) Bu, her sınıfı sınıf adı ile bir string-> TClass hashmap'inde anahtar olarak kaydeder.

Her bileşen TComponent, tek bir argüman alan sanal bir kurucuya sahip olan iner Owner: TComponent. Herhangi bir bileşen, kendi başlatmasını sağlamak için bu yapıcıyı geçersiz kılabilir. DFM okuyucu bir sınıf adı okuduğunda, yukarıda belirtilen hashmap'de adı arar ve karşılık gelen sınıf referansını alır (veya yoksa bir istisna oluşturur), daha sonra üzerinde iyi olduğu bilinen sanal TComponent yapıcısını çağırır. çünkü kayıt fonksiyonu TComponent'ten inmek için gerekli olan bir sınıf referansı alır ve uygun tipte bir nesne ile sonuçlanırsınız.

Bu eksik, WinForms eşdeğeri ... iyi ... açıkça söylemek için büyük bir karmaşa, herhangi bir yeni .NET dilinin kendi form (de) serileştirmesini tamamen yeniden uygulamasını gerektirir. Bunu düşündüğünüzde bu biraz şok edici; CLR'ye sahip olmanın tüm amacı, birden çok dilin aynı temel altyapıyı kullanmasına izin vermek olduğundan, DFM tarzı bir sistem mükemmel bir anlam ifade ederdi.

uzayabilirlik

Yazdığım bir resim yöneticisi sınıfına bir veri kaynağı (resim dosyalarınıza giden yol gibi) verilebilir ve ardından koleksiyonda olmayan ancak veri kaynağında bulunan bir adı almaya çalışırsanız yeni resim nesnelerini otomatik olarak yükleyebilirsiniz. class ofOluşturulacak yeni nesnelerin sınıfını temsil eden temel görüntü sınıfı olarak yazılan bir sınıf değişkenine sahiptir . Varsayılan olarak gelir, ancak özel amaçlı yeni görüntüler oluştururken görüntülerin farklı şekillerde ayarlanması gereken bazı noktalar vardır. (Alfa kanalı olmadan oluşturmak, hareketli grafik boyutunu belirtmek için bir PNG dosyasından özel meta veriler almak vb.)

Bu, büyük miktarda yapılandırma kodu yazarak ve yeni bir nesne oluşturabilecek tüm yöntemlere özel seçenekler ileterek yapılabilir ... veya yalnızca temel görüntü sınıfının bir sanal sınıfını geçersiz kılan bir alt sınıfı yapabilirsiniz söz konusu özellik yapılandırılır ve ardından "varsayılan sınıf" özelliğini geçici olarak gerektiğinde değiştirmek ve ardından geri yüklemek için bir dene / sonla bloğu kullanın. Sınıf referans değişkenleriyle yapmak çok daha basittir ve bunun yerine jenerikler ile yapılabilecek bir şey değildir.



3
A'nın TClassyararlı olduğu durumlarda bazı örnek kodlarla bir veya iki somut örnek verebilir misiniz? Hakkında yapılan cursory internet araştırmamda bunun parametre olarak aktarılabileceğini TClassgörüyorum TClass. Bu, Generics kullanılarak .NET'te yapılır. Fabrika yöntemleri basitçe static.NET ile işaretlenmiştir ve yürütmek için bir sınıf örneği gerektirmez.
Robert Harvey

7
@RobertHarvey: Bana göre, C # , Java / C ++ yeniden yüklendiğinde bakmayı bıraktığımda ve nesnelerle Modula-2 olarak davranmaya başladıktan sonra çok daha anlamlı olmaya başladı. Java ile aynı: herkes C ++ 'dan etkilendiğini söylüyor, ama bu doğru değil. Ana etkisi Objective-C (ve bununla Smalltalk) ve Java, GC ile C ++ yerine tiplerle Smalltalk olarak davrandıktan sonra çok daha mantıklı olacaktır .
Jörg W Mittag

3
@RobertHarvey: TClassderleyici desteği gerektiren temel bir dil özelliğidir. Kendi dilinizi yazmadan “kendi dilinizi yazamazsınız” ve .NET için bile yeterli olmaz çünkü nesne modeli tek tek diller tarafından değil CLR tarafından tanımlanır. Kelimenin tam anlamıyla .NET çerçevesinin bir parçası olması gereken bir şey veya var olamaz.
Mason Wheeler

4
Her şeyden önce, .NET'in aslında bir "Borland" ürünü olmadığını kesinlikle söyleyebilirim. Bunu nasıl bilebilirim? Delphi'yi geliştiren orijinal çekirdek ekibin bir parçasıydım. Anders, Chuck, Gary ve diğerleriyle yakın çalıştım. Elbette, bunu bildiğinizden eminim. .NET'te bir sınıf başvurusunun varlığına gelince (TClass ve benzer yapılar denir), zengin çalışma zamanı erişilebilir tür bilgilerinin varlığı nedeniyle büyük olasılıkla gereksiz görülüyordu. Delphi başlangıçta çok daha az tip bilgiye sahipti ve sınıf referansları bir uzlaşma oldu.
Allen Bauer

Yanıtlar:


5

.NET (CLR), ilk günlerde "COM + çalışma zamanı" olarak adlandırılan Microsoft'un Bileşen Nesne Modeli'nin (COM) üçüncü neslidir. Microsoft Visual Basic ve COM / ActiveX denetimleri pazarının belirli CLR mimari uyumluluk seçenekleri üzerinde Borland Delphi'den çok daha fazla etkisi oldu. (Kuşkusuz, Delphi'nin ActiveX denetimlerini benimsemesi kesinlikle ActiveX ekosisteminin büyümesine yardımcı oldu, ancak COM / ActiveX Delphi'den önce vardı)

COM mimarisi C (C ++ değil) üzerinde çalışıldı ve sınıflar yerine arayüzlere odaklandı. Ayrıca desteklenen bir nesne nesnesi, yani bir COM nesnesinin aslında birkaç farklı nesneden oluşabileceği anlamına gelir ve IUnknown arayüzü bunları birbirine bağlar. Ancak IUnknown'ın mümkün olduğunca dilden bağımsız olacak şekilde tasarlanan COM nesnesi oluşturmada hiçbir rolü yoktu. Nesne oluşturma genellikle IClassFactory ve yansıma ITypeLibrary ve ilgili arabirimler tarafından işlendi. Endişelerin bu ayrımı uygulama dilinden bağımsızdı ve her çekirdek COM arayüzünün özellikleri minimal ve dik tutuldu.

COM ve ActiveX denetimlerinin popülaritesinin bir sonucu olarak, .NET mimarisi COM IUnknown, IClassFactory ve ITypeLibrary'yi desteklemek için oluşturuldu. COM'da, bu arayüzler mutlaka aynı nesnede değildi, bu yüzden bunları bir araya getirmek mutlaka mantıklı değildi.

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.