Neden kısmi sınıflar kullanılıyor?


72

Anladığım kadarıyla, partialanahtar kelime bir sınıfın birkaç kaynak dosya arasında bölünmesine izin vermekten başka bir şey yapmaz. Bunu kod organizasyonu dışında yapmak için herhangi bir sebep var mı? Bunun için oluşturulan UI sınıflarında kullanıldığını gördüm.

Tam bir anahtar kelime oluşturmak için kötü bir neden gibi görünüyor. Bir sınıf birden fazla dosya gerektirecek kadar büyükse, muhtemelen çok fazla şey yapıyordur. Belki de bir sınıfı tamamlamak için başka bir programcının sınıfını kısmen tanımlamak için kullanabileceğinizi düşündüm, fakat soyut bir sınıf yapmak daha iyi olur.


10
Bu da gerçekten bir "bütün anahtar kelime" değil. Bu bir var içeriksel anahtar kelime . partialsadece daha önce geldiğinde bir şey ifade eder class. Kodun diğer bölümlerinde, vb. Bir tanımlayıcı adı olarak kullanabilirsiniz.
Dean Harding,

4
Onları kullanırsanız ve oluşturulan kod için değilse, sizden nefret ediyorum. Şahsen değilsin ama genelde. Kısmi sınıflar arasında kod aramaktan nefret ediyorum.
Steven Evers

3
Kodları araştırmak zor değil, kısmi bölümün hangi kısmına bakarsanız bakın, VS'de açılan tüm sınıf yöntemleri hala görünmektedir. Diğer kod navigasyonları da gayet iyi çalışıyor (ya akıllıca R # tarzı navigasyon ya da iyi eski shift-ctrl-f)
Steve

2
Kısmi sınıfların ayrı dosyalar halinde olması gerektiği yanlış bir anlama gelir.
Bart,

Yanıtlar:


110

Sınıfın bir bölümünün bazı özel araçlar tarafından üretildiği her senaryoda çok kullanışlıdır, çünkü oluşturulan sınıfa devralmadan oluşturulan koda özel mantık eklemenizi sağlar. Btw. Aynı sebepten dolayı kısmi yöntemler de vardır.

Sadece UI ile ilgili değil, aynı zamanda Linq-To-Sql veya Entity Framework gibi diğer teknolojiler de oldukça yoğun kullanıyor.


44
Ayrıca, oluşturulan kodu sürüm kontrolü dışında bırakırken kodunuzu sürüm kontrolü altında tutmanıza olanak tanır.
Frank Shearar

3
İyi nokta, bunu hiç düşünmedim. Sadece pratikte istismara uğradığını gördüm. (Kötü) programcıların dosya boyutunu yönetilebilir tutmanın bir yolu.
Martin Wickman

1
Kullandığım en iyi örnekler: a) sınıfları genişletmek istediğiniz Linq to SQL veri bağlamları için; b) web servislerinden geçen dersleri genişletmek. Her iki durumda da bu bir kötüye kullanım değildir, ne de dosya boyutlarını yönetilebilir tutmak için bir araç değildir ... Bu şekilde kullanıldığını görmek için mutsuz bir şekilde mutsuzum (ve adımlar
atardım

3
WinForm sınıfları, kontrolleri oluşturan tüm tasarımcı kodlarını gizlemek için kullanır (özellikle tasarımcı, yarattığı tüm kodları rastgele yeniden sıralamayı sever çünkü farketme / suçlamada büyük karışıklıklara neden olur) ve XML ile çalışıyorsanız, XSD aracı kodunuzu otomatik olarak oluşturulan sıralamadan ayırmanıza izin veren yeniden şema dosyasında kısmi sınıflar oluşturun.
Dan Neely,

2
@ MartinWickman mutlaka kötü değil. Tanrının nesnelerini miras kurallarına göre yeniden düzenlemek için iyi bir başlangıç ​​noktasıdır. Öncelikle büyük sınıfları ayrı dosyalara bölerek peyzajı temizlemeye çalışın. (
Yorumunuzun

26

Söylediğiniz gibi, genellikle oluşturulan kodu ayırmak için kullanılır. Genellikle sınıfların / dosyaların büyüklüğü ile ilgisi yoktur.

Oluşturulan kodun ayrılmasının faydası, stillerden biridir. Oluşturulan kod oldukça çirkin ve okunaksız olabilir ve birçok kodlama standardında başarısız olabilir (ve StyleCop kontrolleri), ancak sorun yok, hiç kimse onu okumalı veya doğrudan korumalı. Yani, onu başka bir dosyada "gizlerseniz", sınıfın geri kalanının standartlara uyduğundan emin olmaya odaklanabilirsiniz, StyleCop kontrollerini ve benzerlerini geçer.

Kullandığım başka bir alan, bir sınıfın çoklu arayüzler uyguladığı alandır, bu uygulamayı kişisel olarak ayırmak için uygulamayı ayırmak oldukça güzel olabilir, ancak bu daha çok kişisel tercih meselesi olmasına rağmen, kodlama standartlarının gerektirdiği hiçbir şeyi görmedim ( veya önlemek) bu.


9
Arayüz uygulamalarını ayırmak için sınıf kısmi kullanmayı hiç düşünmedim, bu mükemmel bir fikir.
Mark Booth

Tarzdan çok daha fazlası. Bir kod oluşturucunun geliştiricileri, oluşturucu tarafından yönetilen bir dosyadaki kodu düzenlemenizi sağlamak için kasnaklardan atlamak zorunda kalacaklar ve o zaman bile sorunlu olurdu. Bana # 1 yarar, size jeneratörün dokunacağı / dokunamayacağı kodunu yazmak için bir yer veriyor. Bu oldukça somut bir avantaj.
Daniel,

19

Çalıştığım geliştiricilerden biri, birkaç hafta önce kontrolden çıkmış ve çok sayıda kamu yöntemine sahip dev Tanrı sınıflarının yeniden yapılandırılmasında onlar için oldukça iyi bir kullanım için geldi: her bir parçanın mantıksal işlevlerini ayırarak Sınıfı ayrı bir kısmi sınıflar halinde, fiziksel olarak var olan işlevselliği bozmadan sınıfları olması gereken daha atomik birimlere ayırarak, ortak olanı ve olmayanı görmenizi sağlar. İlk aşama olarak bununla, kısmi kişileri kendi bağımsız sınıflarına daha kolay ayırabilir ve kod tabanı boyunca uygulayabilirsiniz. Bunun iyi bir fikir olduğunu düşündüm.

Ancak, genel olarak, yalnızca yeni kod yazarken makine tarafından oluşturulan sınıfları artırmak için kullanılması gerektiğini düşünüyorum.


1
Bunun nasıl kullanışlı olabileceğini görebiliyorum. Bunun dilde olmasının gerekçesi olup olmadığı ... Bilmiyorum. Makine yine de kodun başka bir hikayesini yarattı.
Michael K

2
Evet, dilde olmasının bir gerekçesi değil, ancak bunları kullanmanın ilginç bir yolu.

18

Kısmi insanların mantıklı olduğu birkaç faydalı senaryo düşünebilirim, çoğu kendimi projelerimde kullanıyorum:

  • Ayırmak için Aracı / IDE / Tasarımcı sen muhafaza edilir koddan kodu oluşturulur. Bunun iyi bir örneği, Form.Designer.cspencereler için uygulamalar tarafından oluşturulan tasarımcının kodunu içeren dosya uygulamalarıdır. Diğer birçok .NET formatında, projenizi oluştururken potansiyel olarak yeniden oluşturulabilen bazı araç kodları da vardır ve bu nedenle tüm özel değişiklikleriniz silinir. Ayırma, kodunuzu korumanıza ve değişikliklerinizi bu tür otomatik değişikliklerden korumanıza yardımcı olur.

  • Uygulamada çok fazla kod içeren birden fazla arayüz uyguladığınızda. Ben bu gibi adlandırma, her tür arayüzü için ayrı kısmi dosyasını kullanmak eğilimindedir: {Class}.{Interface}.cs. IDE'de hangi {Class}uygulamaların ve nasıl bir arayüz oluşturduğunu görmek benim için kolay .

  • Sınıf bir veya daha fazla iç içe sınıf içermesi gerektiğinde , özellikle de ayrı bir dosyaya koymak için yeterince kodları vardır. Yukarıdaki kalıba sadık {Class}.{NestedClass}.cskalarak iç içe geçmiş her sınıf için adlandırma kuralını kullanırdım . Benzer bir uygulama Virtlink'in cevabı tarafından da belirtildi .

  • Uzatma yöntemlerinistatic tutacak sınıfları yazarken . Örneğin , jenerik ve jenerik olmayan koleksiyonlarda olduğu gibi, aynı uzantı metodu mantığını benzer sınıflara veya arayüzlere sunmak çoğu zaman geçerli olacaktır . Tek bir sınıf veya arayüz için tüm uzatma yöntemlerini statik sınıfın ayrı bir kısmına koyardım. Örneğin, arabirim için tüm uzantı yöntemlerini tek bir yerde, başka bir dosyada da aynı yöntemleri kullandım . Başka bir yaklaşım, aynı yöntemi (aşırı yüklerinin tümünü) aynı kısmi içine koymak, yani parametre için olası tüm sınıfları -ReverseIListIList<T>thisReversetek dosyada uygulamalar. Ayrılığın kod hacmi veya sizin veya kuruluşunuzun yapabileceği bazı iç sözleşmeler açısından hangisinin daha iyi gerekçelendireceğine bağlıdır.

  • Bunu kullanmıyorum, ancak burada tarif edeceğim yaklaşımı beğenecek bazı C / C ++ milletlerini gördüm: sadece kısmi yöntemlerle sınıf için kısmi oluşturun . Bu, arabirimleri tanımlamanın ve yöntem bildirimini uygulamadan ayırmanın C / C ++ yolunu andırır.

  • Sadece mantıksal kaygılarla ayrılma . Birden fazla mantıksal işlem kümesini kendi içinde birleştiren büyük bir sınıfla çalışıyorsanız, mantıksal olarak ilgili her kodu ayrı bir kısmi olarak ayırabilirsiniz. Genellikle bu tür sınıfların varlığı, kaygılar ilkesinin ayrılmasına aykırıdır, ancak çoğu zaman, özellikle eski kod tabanları için, gerçek hayattaki bir durum gözlenir. Diğer kullanıcı Steve Evers, bu soruya verdikleri cevapta , tanrı objeleri adında kendilerine bahsetti.. İşimi kolaylaştırmak ve yeniden düzenlemeyi daha şeffaf hale getirmek için bu kadar büyük dosyaların yeniden yapılandırılmasından önce kodu bölmek için şahsen kısmi sınıfların yaklaşımını kullanırdım. Bu aynı zamanda SVN gibi sistemlerin sürümleri söz konusuysa, potansiyel olarak neden olacağım çatışmaları da azaltacaktır.


14

Kimsenin bahsettiğini görmedim: partialiç içe sınıfları kendi dosyalarına koymak için kullanıyorum .

Bütün kod dosyalarım sadece bir sınıf, yapı, arayüz veya enum içeriyor. Dosya adları, aradığınız şeyin adını gösterdiğinde, bir nesnenin tanımını bulmayı çok daha kolaylaştırır. Visual Studio, proje klasörlerini ad alanlarıyla eşleştirmeye çalıştığından, dosya adlarının sınıflarla eşleşmesi gerekir.

Bu aynı zamanda bir sınıf demektir NestedClassiçine yuvalanmış MyClassbenim projelerde, bu kendi dosyasına sahip olacaktır: MyClass.NestedClass.cs.

partial class MyClass
{
    private class NestedClass
    {
        // ...
    }
}

1
Birinin bu cevabı neden oy kullandığını merak ediyorum. Bahsedilen uygulama ne bir kalıp karşıtıdır, ne de bildiğim sorunlara neden olur.
Ivaylo Slavov

1
Bu aynı zamanda, sınıf dosyalarının küçük tutulması (kod satırları) sorununu çözerken yine de bir iç sınıfa ait kodun uygun şekilde kapsanmasına izin verir.
redcalx

10

Oluşturulan kodu kullanmak dışında, onları yalnızca tanrı nesnelerini örtbas etmek için kullandıklarını gördüm . Yeni bir kod temeli anlamaya çalışmak veya aynı nesne olan birden fazla kaynak dosya arasında gezinmek çok sinir bozucu.

Bu yüzden sorduğumda Why use partial classes?cevap vereceğim: Oluşturulan kodu kullanmıyorsanız yapma.


+1. İlk defa bu tip nesnelere ad (tanrı objeleri) dendiğini ve hatta resmi olduğunu görüyorum. Yeni bir şey öğrenmek için asla geç değildir.
Ivaylo Slavov

6

Kod organizasyonu tek nedenidir, ancak ilk bakışta göründüğünden daha derine iniyor. Parçaların üretildiği kısmi sınıflarınız varsa, kolayca yapabilirsiniz:

  • Yazdığınız sınıflardaki manuel değişiklikleri tespit etmek zorunda kalmadan kodu yeniden oluşturun (böylece bu parçaların üzerine yazmazsınız).
  • Oluşturulan kısmi sınıfları test kapsamı, kaynak kontrolü, ölçümler vb.
  • Kalıtım stratejinizi etrafına yerleştirmeye zorlamadan oluşturulan kodu kullanın (yine de diğer sınıflardan miras alabilirsiniz).

1

Oluşturulan / ima edilen sınıfların kısmi olarak ilan edildiği birkaç yer de vardır, bu nedenle Dev'in onları genişletmesi gerekiyorsa, her yerden devralma ve devralma konusunda karışıklık duymadan tam erişime sahip olurlar. Bazı örnekleri yakalamaya çalışmak istiyorsanız, IIS altında ilk kez bir webforms sitesi çalıştırdıktan sonra, asp.net temp alanında oluşturulan sınıflara bakın.


1

Onlar için kirli bir kullanım düşünebilirim.

Ortak işlevselliğe ihtiyaç duyan bazı sınıflarınız olduğunu varsayalım, ancak bu işlevselliği üstlerindeki miras zincirine enjekte etmek istemezsiniz. Veya, ortak bir yardımcı sınıf kullanan bir dizi sınıfa sahipsiniz.

Temel olarak, birden fazla kalıtım yapmak istiyorsunuz, ancak C # no likey. Yani yaptığınız şey esasen C / C ++ 'da #include olanı oluşturmak için kısmi kullanmaktır;

Tüm işlevselliği bir sınıfa yerleştirin veya yardımcı sınıfı kullanın. Sonra yardımcı X zamanlarını kopyalayın ve kısmi A, B, C sınıfını yeniden adlandırın. ve A, B, C sınıflarına kısmi olarak koyun.

Yasal Uyarı: Evet, bu kötü. Asla yapma - özellikle diğer insanları sana kızdıracaksa.


Katmalar. Bu, el ile kopyalamayı önlemek için T4 ile birleştirilebilir ...
Peter Taylor 20

Belirtildiği gibi, bu karışımlara yakından benzemektedir. Ancak, “özellikler” olarak bilinen bir konsepte yaklaşıyorsunuz ve elde etmeye çalıştığınız şeyi güvenle ele alacaklar . Publius-ovidius.livejournal.com/314737.html adresinde agnostik bir tanımım var . C # için temiz bir uygulama aradım, ancak bir tane görmedim.
Ovid
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.