.NET'teki tüm sınıflar neden Object sınıfından miras alınır?


16

Benim için çok ilginç olan avantaj, çerçeve için "küresel kök sınıf" yaklaşımını veriyor. Basitçe ifade etmek gerekirse, .NET framework tüm sonuçlara uygun genel işlevselliğe sahip bir kök nesne sınıfına sahip olacak şekilde tasarlanmıştır .

Günümüzde dahili kullanım için yeni bir çerçeve tasarlıyoruz (SAP platformu altındaki çerçeve) ve hepimiz iki kampa ayrıldık - birincisi, bu çerçevenin küresel kökü olması gerektiğini düşünen, ikincisi ise tersini düşünen.

"Küresel kök" kampındayım. Ve bu yaklaşımın iyi esneklik ve geliştirme maliyetlerinde azalma sağlayacağı nedenlerim, artık genel işlevselliği geliştirmeyeceğimiz için.

Bu nedenle, .NET mimarlarını çerçeve tasarlamaya bu şekilde iten nedenleri bilmek çok ilgimi çekiyor.


6
.NET Framework'ün genelleştirilmiş bir yazılım geliştirme ortamının parçası olduğunu unutmayın. Sizinki gibi daha spesifik çerçevelerin "kök" bir nesneye ihtiyacı olmayabilir. object.NET çerçevesinde bir kök var çünkü tüm nesneler arasında bazı temel yetenekler sağlıyor, ToString()veGetHashCode()
Robert Harvey

10
".NET mimarlarını çerçeve oluşturmaya gerçekten neden ittiğini bilmek çok ilginç." Bunun çok iyi üç nedeni var: 1. Java bunu böyle yaptı, 2. Java bunu böyle yaptı ve 3. Java bunu böyle yaptı.
dasblinkenlight

2
@vcsjones: ve Java zaten wait()/ notify()/ notifyAll()ve ile kirlenmiş durumda clone().
Joachim Sauer

3
@daskblinkenlight Thats poo. Java bunu böyle yapmadı.
Dante

2
@dasblinkenlight: FYI, Java şu anda C #, lambdas, LINQ fonksiyonları, vb. ile kopyalanan biridir ...
user541686

Yanıtlar:


18

Bunun en acil nedeni Object, C-stili "İhtiyacınız olan her şey için tekrar yazın" yerine herhangi bir şey içerebilecek kaplar (jeneriklerden önce). Tabii ki, tartışmasız, her şeyin belirli bir sınıftan miras alması ve daha sonra bu gerçeği her tür güvenlik türünü tamamen kaybetmek için kötüye kullanması fikri o kadar korkunç ki, dili jeneriksiz olmadan göndermede dev bir uyarı ışığı olmalı ve aynı zamanda bu Objectyeni kod için tamamen gereksizdir.


6
Bu doğru cevap. Tek neden jenerik desteğin olmayışı idi. Diğer "ortak yöntemler" argümanları gerçek argümanlar değildir, çünkü ortak yöntemlerin ortak olması gerekmez - Örnek: 1) ToString: çoğu durumda istismar edilir; 2) GetHashCode: programın ne yaptığına bağlı olarak, çoğu sınıfın bu yönteme ihtiyacı yoktur; 3) GetType: örnek bir yöntem olmak zorunda değildir
Codism

2
.NET, her şeyin belirli bir sınıftan miras alması gerektiği fikrini "kötüye kullanarak" "her türlü güvenlik türünü tamamen kaybeder". Etrafında Objectyazılabilen void *, C ++ ' da yazılamayan herhangi bir bok kodu var mı ?
Carson63000

3
Kim void*daha iyi olduğunu düşündüğümü söyledi ? Öyle değil. Eğer birşey. daha da kötü .
DeadMG

void*C, tüm örtülü işaretçi yayınlarıyla daha kötüdür, ancak C ++ bu konuda daha katıdır. En azından açıkça yayınlamalısın.
Tamás Szelei

2
@fish: Bir terminoloji tartışması: C'de "örtük oyuncular" diye bir şey yoktur. Cast, bir dönüşüm belirten açık bir operatördür. "Örtük işaretçi dönüşümleri " demek istediniz .
Keith Thompson

11

Eric Lippert'in bir keresinde System.Objectsınıftan miras almanın 'müşteri için en iyi değeri' sağladığını söylediğini hatırlıyorum . [değiştir: evet, burada söyledi ]:

... Ortak bir taban türüne ihtiyaç duymazlar . Bu seçim zorunlu olarak yapılmadı. Müşteri için en iyi değeri sağlama arzusundan yapılmıştır.

Bir tip sistemi veya bu konuda başka bir şey tasarlarken, bazen karar noktalarına ulaşırsınız - X'e ya da X'e karar vermelisiniz ... Ortak bir taban türüne sahip olmanın faydaları maliyetlerden ve net faydadan daha ağır basar. tahakkuk eden ortak taban türü olmaması net faydadan daha büyüktür. Bu yüzden ortak bir taban türüne sahip olmayı seçiyoruz.

Bu oldukça belirsiz bir cevap. Daha spesifik bir cevap istiyorsanız, daha spesifik bir soru sormayı deneyin.

Sınıftan türetilen her şeye sahip olmak, System.Objectçok saygı duyduğum bir güvenilirlik ve kullanışlılık sağlar. Tüm nesnelerin bir tip ( GetType) olacağını, CLR'nin sonlandırma yöntemlerine ( Finalize) uygun olacağını GetHashCodeve koleksiyonlarla uğraşırken bunları kullanabileceğimi biliyorum.


2
Bu kusurlu. İhtiyacınız yok GetType, typeofişlevselliğini değiştirmek için genişletebilirsiniz . O Finalizezaman aslında, birçok tür tamamen tamamlanamaz ve anlamlı bir Sonlandırma yöntemine sahip değildir. Buna ek olarak, birçok tip, özellikle böyle bir şey için tasarlanmayan ve asla kamuya açıklanmayan iç tipler için yıkanabilir veya dizgiye dönüştürülemez. Tüm bu türlerin arayüzleri gereksiz yere kirli.
DeadMG

5
Hayır, kusurlu değil - Kullanabileceğin iddia etti asla GetType, Finalizeya GetHashCodeher için System.Object. Sadece istersen orada olduklarını söyledim. "Arayüzleri gereksiz yere kirlenmiş" gelince, orijinal elippert teklifime değineceğim: "müşteri için en iyi değer". Açıkçası .NET ekibi ödünleşmelerle uğraşmak istiyordu.
gws2

Gerekli değilse, arayüz kirliliği. "İsterseniz" asla bir yöntem eklemek için iyi bir neden değildir. Sadece orada olmalı çünkü buna ihtiyacınız var ve tüketicileriniz onu arayacak . Aksi halde, iyi değil. Olarak Ayrıca, Lippert alıntı, yetki safsata bir itiraz o da "It adlı iyiliği" dışında bir şey söylüyor.
DeadMG

Senin nokta (lar) @DeadMG tartışmaya çalışmıyorum - soru özellikle "Neden .NET tüm sınıflar küresel Object sınıfından devralır" oldu ve bu nedenle çok yakın .NET ekibi yakın biri tarafından önceki bir yazı ile bağlantılı Belirsiz de olsa yasal bir yanıt veren Microsoft, .NET geliştirme ekibinin neden bu yaklaşımı seçtiğine ilişkin bir cevap verdi.
gws2

Bu sorunun cevabı olamayacak kadar belirsiz.
DeadMG

4

Java ve C # tasarımcılarının bir kök nesne eklediğini düşünüyorum, çünkü ücretsiz öğle yemeğinde olduğu gibi onlar için esasen ücretsizdi .

Bir kök nesne eklemenin maliyeti, ilk sanal işlevinizi eklemenin maliyetine çok eşittir. Hem CLR hem de JVM, nesne sonlandırıcılara sahip çöp toplanmış ortamlar olduğu java.lang.Object.finalizeiçin, System.Object.Finalizeyönteminiz veya yönteminiz için en az bir sanal ağa sahip olmanız gerekir . Bu nedenle, kök nesnenizi eklemenin maliyeti zaten ön ödemelidir, ödemeden tüm avantajları elde edebilirsiniz. Bu her iki dünyanın da en iyisidir: ortak bir kök sınıfa ihtiyaç duyan kullanıcılar istediklerini alırlar ve daha az umursamayan kullanıcılar sanki orada değilmiş gibi programlayabilirler.


4

Bana öyle geliyor ki üç sorunuz var: biri .NET'e ortak bir kök getirildi, ikincisi bunun avantajları ve dezavantajları ve üçüncüsü, bir çerçeve öğesinin küresel olması için iyi bir fikir olup olmadığı kök.

.NET'in neden ortak bir kökü var?

En teknik anlamda, ortak bir köke sahip olmak yansıma ve pre-jenerik konteynerler için gereklidir .

Buna ek olarak, bildiklerime göre, Java gibi temel yöntemlerle ortak bir köke sahip olmak equals()ve hashCode()Java'da çok olumlu bir şekilde alındı ​​ve C # (diğerleri arasında) Java'dan etkilendi, bu yüzden de bu özelliğe sahip olmak istediler.

Bir dilde ortak bir köke sahip olmanın avantajları ve dezavantajları nelerdir?

Ortak bir köke sahip olmanın avantajı:

  • Sen izin verebilir tüm nesneleri gibi, önemli olduğunu düşündüğümüz belli özelliğe sahip etmek equals()ve hashCode(). Bu, örneğin, Java veya C # 'daki her nesnenin bir karma haritasında kullanılabileceği anlamına gelir - bu durumu C ++ ile karşılaştırın.
  • Bilinmeyen türdeki nesnelere başvurabilirsiniz - örneğin, genel jenerik kapsayıcıların yaptığı gibi etrafta bilgi aktarıyorsanız.
  • Bilinmeyen türdeki nesnelere başvurabilirsiniz - örneğin yansıma kullanırken.
  • Nadir durumlarda, farklı ve başka türlü ilgisiz türlerde olabilen bir nesneyi kabul etmek istediğinizde kullanılabilir - örneğin, benzer bir printfyöntemin parametresi olarak .
  • Sadece bir sınıfı değiştirerek tüm nesnelerin davranışlarını değiştirme esnekliği sağlar. Örneğin, C # programınızdaki tüm nesnelere yöntem eklemek istiyorsanız, öğesine bir uzantı yöntemi ekleyebilirsiniz object. Belki çok yaygın değil, ama ortak bir kök olmadan bu mümkün olmazdı.

Ortak bir köke sahip olmanın dezavantajı:

  • Daha doğru bir tür kullanmış olsanız bile, bir değere sahip bir nesneye atıf yapmak kötüye kullanılabilir.

Çerçeve projenizde ortak bir kök ile gitmeli misiniz?

Çok öznel, elbette, ama yukarıdaki pro-con listesine baktığımda kesinlikle evet cevabı verirdim . Özellikle, pro listesindeki son madde işareti - daha sonra kökü değiştirerek tüm nesnelerin davranışını değiştirme esnekliği - kökte yapılan değişikliklerin istemciler tarafından kabul edilmesinin bir bütündeki değişikliklerden daha muhtemel olduğu bir platformda çok yararlı olur. dil.

Ayrıca - bu daha öznel olsa da - ortak bir kök kavramını çok zarif ve çekici buluyorum. Ayrıca bazı takım kullanımını kolaylaştırır, örneğin bir araçtan bu ortak kökün tüm torunlarını göstermesini ve çerçevenin türlerine hızlı ve iyi bir genel bakış almasını istemek artık kolaydır.

Tabii ki, türlerin bunun için en azından biraz ilişkili olması gerekir ve özellikle, sadece ortak bir köke sahip olmak için "is-a" kuralını asla feda etmem.


Bence c # sadece Java tarafından etkilenmedi, bir noktada -was- Java. Microsoft artık Java'yı kullanamıyordu, bu yüzden milyarlarca yatırımları kaybediyordu. Zaten yeni bir isimleri olan dili vermekle başladılar.
Mike Braun

3

Matematiksel olarak, üst içeren bir dil sistemine sahip olmak biraz daha zariftir ve bir dili biraz daha tamamen tanımlamanıza izin verir.

Bir çerçeve oluşturuyorsanız, işler varolan bir kod tabanı tarafından tüketilecektir. Çerçeveyi tüketen diğer tüm türler mevcut olduğundan evrensel bir süper tipe sahip olamazsınız.

At o noktada, karar ortak bir taban sınıfı ne yaptığınızı bağlıdır olması. Birçok şeyin ortak bir davranışa sahip olması ve bu şeylere sadece ortak davranış yoluyla atıfta bulunmak çok nadirdir .

Ama olur. Eğer öyleyse, o zaman ortak davranışı soyutlamada ilerleyin.


2

Kök nesnesi için zorlandı çünkü çerçevedeki tüm sınıfların belirli şeyleri desteklemesini istediler (bir karma kodu alma, bir dizeye dönüştürme, eşitlik kontrolleri, vb.). Hem C # hem de Java, bir nesnenin tüm bu ortak özelliklerini bazı kök sınıflarına koymayı yararlı buldu.

OOP prensiplerini veya herhangi bir şeyi ihlal etmediklerini unutmayın. Object sınıfındaki her şey , sistemdeki herhangi bir alt sınıfta (read: any class) anlamlıdır . Bu tasarımı benimsemeyi seçerseniz, bu deseni takip ettiğinizden emin olun. Yani, kökünüze sisteminizdeki her bir sınıfa ait olmayan şeyleri dahil etmeyin. Bu kuralı dikkatli bir şekilde uygularsanız, tüm sistem için yararlı, ortak kod içeren bir kök sınıfına sahip olmamanız için herhangi bir neden göremiyorum.


2
Bu hiç doğru değil. Asla hash edilmemiş, asla yansıtılmamış, asla dizgiye dönüştürülmemiş birçok dahili sınıf vardır. Gereksiz kalıtım ve gereksiz yöntemler kesinlikle yapar birçok ilkelerini ihlal eder.
DeadMG

2

Birkaç neden, tüm çocuk sınıflarının paylaşabileceği ortak işlevsellik. Ayrıca çerçeve yazarlarına her şeyin kullanabileceği çerçeveye birçok başka işlev yazma yeteneği de verdi. ASP.NET önbelleğe alma ve oturumları buna örnek olarak gösterilebilir. Neredeyse her şey saklanabilir, çünkü nesneleri kabul etmek için ekleme yöntemleri yazdılar.

Bir kök sınıfı çok çekici olabilir, ancak kötüye kullanımı çok, çok kolaydır. Bunun yerine bir root arayüzüne sahip olmak mümkün müdür? Ve sadece bir veya iki küçük yönteminiz mi var? Yoksa bu, çerçevenize gerekenden çok daha fazla kod ekler mi?

Yazdığınız çerçevedeki tüm olası sınıflara hangi işlevselliği göstermeniz gerektiğini merak ediyorum. Bu gerçekten bütün nesneler tarafından kullanılacak mı? Ya da çoğu tarafından mı? Kök sınıfını oluşturduktan sonra, insanların rasgele işlevsellik eklemesini nasıl engelleyeceksiniz? Yoksa rastgele değişkenler "global" olmak ister mi?

Birkaç yıl önce kök sınıfı oluşturduğum çok büyük bir uygulama vardı. Birkaç aylık bir gelişimden sonra, orada hiçbir işi olmayan kodla dolduruldu. Eski bir ASP uygulamasını dönüştürüyorduk ve kök sınıf, geçmişte kullandığımız eski global.inc dosyasının yerini aldı. Bu dersi zor yoldan öğrenmek zorunda kaldım.


2

Tüm bağımsız yığın nesneleri şunlardan miras alır Object; mantıklıdır, çünkü tüm bağımsız yığın nesnelerinin türlerini tanımlama gibi belirli ortak yönleri olmalıdır. Aksi takdirde, çöp toplayıcının bilinmeyen türde bir yığın nesnesine başvurusu olsaydı, o nesne ile ilişkili bellek bloğundaki hangi bitlerin diğer yığın nesnelerine referans olarak kabul edilmesi gerektiğini bilemezdi.

Ayrıca, tip sistemi içinde, yapı elemanlarını ve sınıf elemanlarını tanımlamak için aynı mekanizmayı kullanmak uygundur. Değer tipi depolama konumlarının (değişkenler, parametreler, alanlar, dizi yuvaları, vb.) Davranışı, sınıf tipi depolama konumlarından çok farklıdır, ancak bu tür davranışsal farklılıklar kaynak kodu derleyicilerinde ve yürütme motorunda ( JIT derleyicisi) yazın.

Bunun bir sonucu, bir değer türünün tanımlanmasının iki türü etkin bir şekilde tanımlamasıdır - bir depolama yeri türü ve bir yığın nesnesi türü. Birincisi dolaylı olarak ikincisine dönüştürülebilir ve ikincisi tipik olarak öncekine dönüştürülebilir. Her iki dönüştürme türü de, söz konusu türün bir örneğinden diğerine tüm genel ve özel alanları kopyalayarak çalışır. Ayrıca, genel kısıtlamaları kullanarak, önce bir kopyasını oluşturmadan arabirim üyelerini doğrudan bir değer türü depolama konumuna çağırmak mümkündür.

Tüm bunlar önemlidir, çünkü değer türü yığın nesnelerine yapılan başvurular değer türleri gibi değil sınıf başvuruları gibi davranır. Örneğin, aşağıdaki kodu ele alalım:

dize testEnumerator <T> (T it) burada T: IEnumerator <string>
{
  var it2 = it;
  it.MoveNext ();
  it2.MoveNext ();
  geri dön.Şu anda;
}
herkese açık geçersizlik testi ()
{
  var theList = yeni Liste <string> ();
  theList.Add ( "Fred");
  theList.Add ( "George");
  theList.Add ( "Percy");
  theList.Add ( "Molly");
  theList.Add ( "Ron");

  var enum1 = theList.GetEnumerator ();
  IEnumerator <string> enum2 = enum1;

  Debug.Print (testEnumerator (enum1));
  Debug.Print (testEnumerator (enum1));
  Debug.Print (testEnumerator (enum2));
  Debug.Print (testEnumerator (enum2));
}

Eğer testEnumerator()yöntem değeri türünde bir depolama konumunu geçirilir, itkimin kamu ve özel alanlar geçmiş-değerden kopyalanan bir örneğini alacaktır. Yerel değişken it2, alanlarının tümü kopyalanan başka bir örneği barındırır it. Arayan MoveNextüzerinde it2etkilemez it.

Yukarıdaki kod, sınıf türünde bir depolama konumu geçirilirse, o zaman iletilen değer it, ve it2, aynı nesneye atıfta bulunur ve böylece MoveNext()bunlardan herhangi birini çağırmak , etkin bir şekilde hepsini çağırır.

Not döküm olduğu List<String>.Enumeratoriçin IEnumerator<String>etkin bir şekilde, bir sınıf tipi bir değer türünden döner. Öbek nesnesinin türü, List<String>.Enumeratorancak davranışı aynı adın değer türünden çok farklı olacaktır.


ToString ()
JeffO'dan

1
Bu tamamen uygulama detayları ile ilgilidir. Bunları kullanıcıya göstermeye gerek yoktur.
DeadMG

@DeadMG: Ne demek istiyorsun? Olarak List<T>.Enumeratorkaydedilen List<T>.Enumeratorbirin gözlemlenebilir davranışı, bir IEnumerator<T>önceki tipte bir değerin her iki tipte bir depolama konumuna kaydedilmesinin numaralandırıcının durumunun bir kopyasını oluşturacağı, ikinci türdeki bir değeri, ikinci türdeki bir depolama konumuna depolamak kopya oluşturmaz.
supercat

Evet, ama Objectbu gerçekle hiçbir ilgisi yok.
DeadMG

@DeadMG: Demek istediğim, bir tür yığın örneğinin System.Int32de bir örneği olduğu System.Object, ancak türdeki bir depolama yerinin System.Int32ne bir System.Objectörneği ne de bir referansı içermesi .
supercat

2

Bu tasarım, Smalltalk'a kadar uzanıyor, ki bu büyük ölçüde neredeyse tüm endişeler pahasına nesne yönelimi peşinde koşma girişimi olarak görüyorum. Bu nedenle, (benim görüşüme göre), diğer teknikler muhtemelen (hatta kesinlikle) daha üstün olsa bile, nesne yönelimini kullanma eğilimindedir.

ObjectKökte tek bir hiyerarşiye sahip olmak (veya benzer bir şey), koleksiyon sınıflarınızı koleksiyon olarak oluşturmayı oldukça kolaylaştırır (bir örnek için) Object, bu nedenle bir koleksiyonun her türlü nesneyi içermesi önemsizdir.

Bu oldukça küçük avantaj karşılığında, dezavantajların bir bütün olsa olsun. İlk olarak, tasarım açısından bakıldığında, gerçekten çılgınca fikirler elde edersiniz. En azından evrenin Java görüşüne göre, Ateizm ve Orman'ın ortak noktası nedir? İkisinin de hashcodeları var! Harita bir koleksiyon mu? Java'ya göre, hayır, değil!

Smalltalk'ın tasarlandığı 70'lerde, bu tür bir saçmalık kabul edildi, çünkü kimse makul bir alternatif tasarlamadı. Smalltalk, 1980'de sonuçlandırıldı ve 1983'e kadar (jenerikleri içeren) Ada tasarlandı. Ada, bazılarının tahmin ettiği türden bir popülerliğe ulaşamamasına rağmen, jenerikleri , monolitik hiyerarşilere özgü delilik olmadan , keyfi tipteki nesnelerin koleksiyonlarını desteklemek için yeterliydi .

Java (ve daha az ölçüde .NET) tasarlandığında, monolitik sınıf hiyerarşisi muhtemelen "güvenli" bir seçenek olarak görülüyordu - problemleri olan, ancak çoğunlukla bilinen problemler. Buna karşın, jenerik programlama neredeyse herkesin (o zaman bile) farkına varmıştı ki , problem için en azından teorik olarak çok daha iyi bir yaklaşımdı, fakat ticari olarak yönlendirilmiş birçok geliştiricinin oldukça zayıf araştırılmış ve / veya riskli (yani ticari dünyada) Ada büyük ölçüde başarısızlıkla sonuçlandı).

Kristal berraklığında olalım: monolitik hiyerarşi bir hataydı. Bu hatanın nedenleri en azından anlaşılabilirdi, ama yine de bir hataydı. Kötü bir tasarım ve tasarım problemleri onu kullanan neredeyse tüm kodları etkiliyor.

Ancak bugün yeni bir tasarım için makul bir soru yok: monolitik bir hiyerarşi kullanmak açık bir hata ve kötü bir fikirdir.


.NET'in gönderilmeden önce şablonların harika ve kullanışlı olduğu biliniyor.
DeadMG

Ticari dünyada Ada , ayrıntı düzeyi nedeniyle değil, işletim sistemi hizmetlerinde standartlaştırılmış arayüzlerin bulunmaması nedeniyle bir başarısızlıktı. Dosya sistemi, grafik, ağ vb. İçin standart bir API yok, Ada'da 'barındırılan' uygulamaların geliştirilmesini son derece pahalı hale getirdi.
kevin cline

@kevincline: Ada'nın pazardaki başarısızlığı nedeniyle bir bütün olarak başarısızlık olarak reddedilmesi etkisine muhtemelen biraz farklı bir şekilde ifade etmeliydim. Ada'yı kullanmayı reddetmek (IMO) oldukça mantıklıydı - ama ondan daha az öğrenmeyi reddetmek (en iyi ihtimalle).
Jerry Coffin

@Jerry: Sanırım C ++ şablonları Ada jeneriklerinin fikirlerini benimsedi, sonra bunları örtük örneklerle büyük ölçüde geliştirdi.
kevin cline

1

Yapmak istediğiniz şey gerçekten ilginç, bitene kadar yanlış mı yoksa doğru mu olduğunu kanıtlamak zor.

Düşünmeniz gereken bazı şeyler:

  • Bu üst düzey nesneyi ne zaman kasten daha belirli bir nesnenin üzerine geçirirsiniz?
  • Sınıflarınızın her birine hangi kodu koymayı düşünüyorsunuz?

Paylaşılan bir kökten faydalanabilecek sadece iki şey bunlar. Bir dilde, çok yaygın olan birkaç yöntemi tanımlamak ve henüz tanımlanmamış nesneleri geçirmenize izin vermek için kullanılır, ancak bunlar sizin için geçerli olmamalıdır.

Ayrıca, kişisel deneyimlerden:

Bir zamanlar arka planı Smalltalk olan bir geliştirici tarafından yazılmış bir araç seti kullandım. Tüm "Data" sınıfları tek bir sınıfı genişletti ve tüm yöntemler o sınıfı aldı - şimdiye kadar çok iyi. Sorun şu ki, farklı veri sınıfları her zaman değiştirilemezdi, bu yüzden şimdi editörüm ve derleyicim bana belirli bir duruma ne geçebileceğim konusunda HERHANGİ BİR yardım veremedi ve her zaman yardımcı olmayan belgelerine başvurmak zorunda kaldım. .

Şimdiye kadar uğraşmam gereken en zor kütüphaneydi.


0

Çünkü OOP'un yolu bu. Herhangi bir şeye işaret edebilecek bir tipe (nesneye) sahip olmak önemlidir. Type nesnesi argümanı her şeyi kabul edebilir. Ayrıca kalıtım var, ToString (), GetHashCode () vb. Her şeyde ve her şeyde kullanılabilir olduğundan emin olabilirsiniz.

Oracle bile böyle bir temel tipe sahip olmanın önemini fark etti ve 2017'de Java'daki ilkelleri kaldırmayı planlıyor


6
Ne OOP yolu ne de önemli. "İyi" dışında hiçbir gerçek argüman vermezsiniz.
DeadMG

1
@DeadMG İlk cümleyi geçmiş bağımsız değişkenleri okuyabilirsiniz. İlkel, nesnelerden farklı davranır, böylece programcıyı, nesneler ve ilkel öğeler için aynı amaç koduna sahip birçok varyant yazmaya zorlar.
Dante

2
@DeadMG iyi olduğunu varsayabileceğinizi ToString()ve GetType()her nesnenin üzerinde olacağını söyledi. Muhtemelen objectherhangi bir .NET nesnesini saklamak için bir değişken türü kullanabileceğinizi belirtmek gerekir.
JohnL

Ayrıca, herhangi bir türün referansını tutabilecek kullanıcı tanımlı bir tür yazmak da mümkündür. Bunu başarmak için özel dil özelliklerine ihtiyacınız yoktur.
DeadMG

Yalnızca belirli kodu içeren düzeylerde bir Nesneniz olmalıdır, asla grafiğinizi birbirine bağlayacak bir nesneniz olmamalıdır. "Nesne" aslında birkaç önemli yöntem uygular ve bir nesneyi türün henüz oluşturulmadığı araçlara aktarmanın bir yolu olarak işlev görür.
Bill K
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.