Kelas vs Modul di VB.NET

157

Apakah dianggap praktik yang dapat diterima untuk menggunakan Modul, bukan Kelas dengan fungsi Anggota bersama di VB.NET?

Saya cenderung menghindari Modul, karena mereka merasa seperti sisa-sisa sisa dari Visual Basic 6.0 dan sepertinya tidak cocok lagi. Di sisi lain, sepertinya tidak ada banyak perbedaan antara menggunakan Modul dan Kelas dengan hanya anggota yang Dibagikan. Tidak sering saya benar-benar membutuhkan banyak hal, tetapi kadang-kadang ada situasi di mana mereka menghadirkan solusi sederhana.

Saya ingin tahu apakah Anda memiliki pendapat atau preferensi apa pun.

Tom Juergens
sumber
10
Satu yang menarik tentang modul adalah bahwa secara default metode dan fungsi yang dideklarasikan di dalamnya memiliki tingkat perlindungan modul, yang berarti Anda dapat secara tidak sengaja menyediakan metode jika Anda lupa menambahkan Privatekualifikasi secara eksplisit . Di kelas, tingkat perlindungan default adalah privat, yang bisa membingungkan perilaku kecuali Anda menyadarinya.
yu_ominae

Jawaban:

207

Modules adalah mitra VB ke statickelas C # . Ketika kelas Anda dirancang hanya untuk fungsi pembantu dan metode ekstensi dan Anda tidak ingin mengizinkan pewarisan dan instantiasi , Anda menggunakan a Module.

Ngomong-ngomong, menggunakan Moduletidak benar-benar subyektif dan itu tidak ditinggalkan . Memang Anda harus menggunakan Modulesaat yang tepat. .NET Framework sendiri melakukannya berkali-kali ( System.Linq.Enumerable, misalnya). Untuk mendeklarasikan metode ekstensi, harus menggunakan Modules.

Mehrdad Afshari
sumber
7
Benar sekali, walaupun saya bisa menggunakan konstruktor pribadi untuk mencegah instantiasi dan pengubah NotInheritable. Sedikit lebih jelek dari Modul tua biasa, tetapi memiliki efek yang sama. Terima kasih atas petunjuk penggunaan Modul dalam Kerangka; Saya akan melihat itu.
Tom Juergens
8
Di bawah tenda, mereka dikompilasi ke kelas dengan atribut [StandardModule]. Selain itu, menggunakan Modul memaksa Anda untuk tidak memiliki hal-hal yang tidak Dibagikan di sana yang merupakan hal yang baik.
Mehrdad Afshari
18
Modul tidak sama dengan kelas statis di C #. Metode dalam modul efektif secara global jika berada dalam ruang nama yang diimpor.
JaredPar
2
@JaredPar: Kata-kata saya mungkin buruk. Saya seharusnya mengatakan rekan-rekan VB ke C # kelas statis. Dari pernyataan itu, saya bermaksud mengatakan menggunakan Modul masuk akal di mana Anda akan menulis kelas statis di C #.
Mehrdad Afshari
3
@Chiwda Lihat msdn.microsoft.com/en-us/library/bb384936.aspx : "Metode ekstensi hanya dapat dideklarasikan dalam modul."
Mehrdad Afshari
34

Saya pikir itu ide yang baik untuk terus menghindari modul kecuali Anda memasukkannya ke ruang nama yang terpisah. Karena dalam metode Intellisense dalam modul akan terlihat dari mana-mana di namespace itu.

Jadi alih-alih ModuleName.MyMethod()Anda berakhir dengan MyMethod()sembulan di mana saja dan jenis enapsulasi enapsulasi ini. (setidaknya di level pemrograman).

Itu sebabnya saya selalu mencoba membuat Kelas dengan metode bersama, tampaknya jauh lebih baik.

dr. jahat
sumber
7
Setuju, saya sedang mengerjakan program lama saat ini (mungkin port VB6 ke VB.NET 1) dengan kelas dan modul. Ada ratusan variabel global, subs, dan fungsi di sekitar sepuluh modul yang berbeda, dan mencari tahu apa yang berasal dari mana dan bagaimana ia dimodifikasi.
yu_ominae
ok ini sudah sangat tua, tetapi relevan dengan pertanyaan saya. Saya bukan orang VB, tetapi saya harus bekerja dengannya. Saya mencoba memecah kelas besar (> 46.000 baris) karena IntelliSense / ReSharper baru saja mati. Saya telah menemukan menggunakan Modul dan hanya merobek potongan besar fungsi ke Modul mereka sendiri tampaknya bekerja, tetapi saya bertanya-tanya apakah saya harus memberikan masing-masing modul ruang nama sendiri juga. Apakah itu perlu? yaitu apakah akan mempercepat IntelliSense hanya dengan Modul, atau akankah Namespaces membantu lebih banyak?
codah
27

Modul sama sekali tidak ditinggalkan dan banyak digunakan dalam bahasa VB. Ini satu-satunya cara misalnya untuk menerapkan metode ekstensi di VB.Net.

Ada satu perbedaan besar antara Modul dan Kelas dengan Anggota Statis. Setiap metode yang didefinisikan pada Modul dapat diakses secara global selama Modul tersedia di namespace saat ini. Akibatnya, Modul memungkinkan Anda untuk menentukan metode global. Ini adalah sesuatu yang tidak bisa dilakukan oleh kelas dengan anggota bersama.

Berikut adalah contoh cepat yang saya gunakan banyak ketika menulis kode VB yang berhenti dengan antarmuka COM mentah.

Module Interop
  Public Function Succeeded(ByVal hr as Integer) As Boolean
    ...
  End Function

  Public Function Failed(ByVal hr As Integer) As Boolean
    ...
  End Function
End Module

Class SomeClass
  Sub Foo()
    Dim hr = CallSomeHrMethod()
    if Succeeded(hr) then
      ..
    End If
  End Sub
End Class
JaredPar
sumber
4
Metode ekstensi ... fitur bagus lain yang selalu ingin saya gunakan, tetapi tidak pernah benar-benar berhasil - yah, ini memberi saya peluang bagus. Saya mendapatkan sedikit tentang ruang lingkup global, dan metode yang tersedia secara global tentu bisa nyaman, tetapi saya merasa sedikit mual tentang penggunaannya yang berlebihan. Bagaimanapun, semua jawaban sejauh ini memberi tahu saya bahwa saya tidak boleh mengabaikan modul; ada alasan bagus untuk menggunakannya dalam situasi yang tepat.
Tom Juergens
12

Dapat diterima untuk digunakan Module. Moduletidak digunakan sebagai pengganti Class. Modulemelayani tujuannya sendiri. Tujuannya Moduleadalah untuk digunakan sebagai wadah untuk

  • metode penyuluhan,
  • variabel yang tidak spesifik untuk apa pun Class, atau
  • variabel yang tidak sesuai dengan apa pun Class.

Moduletidak seperti Classkarena kamu tidak bisa

  • mewarisi dari Module,
  • menerapkan suatu Interfacedengan Module,
  • atau membuat instance dari a Module.

Apa pun di dalam a Moduledapat langsung diakses di dalam Modulemajelis tanpa merujuk pada Modulenamanya. Secara default, tingkat akses untuk a Moduleadalah Friend.

Chandra Malla
sumber
11

Kelas

  • kelas dapat dipakai sebagai objek
  • Data objek ada secara terpisah untuk setiap objek yang dipakai.
  • kelas dapat mengimplementasikan antarmuka .
  • Anggota yang didefinisikan dalam suatu kelas dicakup dalam instance kelas tertentu dan hanya ada selama masa objek .
  • Untuk mengakses anggota kelas dari luar kelas, Anda harus menggunakan nama yang sepenuhnya memenuhi syarat dalam format Object.Member .

Modul

  • Modul tidak dapat dipakai sebagai objek , Karena hanya ada satu salinan data modul standar, ketika satu bagian dari program Anda mengubah variabel publik dalam modul standar, itu akan terlihat oleh seluruh program.
  • Anggota yang dideklarasikan dalam modul dapat diakses publik secara default.
  • Itu dapat diakses oleh kode apa saja yang dapat mengakses modul.
  • Ini berarti bahwa variabel dalam modul standar adalah variabel global yang efektif karena mereka dapat dilihat dari mana saja dalam proyek Anda, dan mereka ada selama umur program.
Suji
sumber
6

Ketika salah satu kelas VB.NET saya memiliki semua anggota yang dibagikan, saya mengonversinya menjadi Modul dengan namespace yang cocok (atau jika tidak sesuai) atau saya membuat kelas tidak dapat diwarisi dan tidak dapat dibangun:

Public NotInheritable Class MyClass1

   Private Sub New()
      'Contains only shared members.
      'Private constructor means the class cannot be instantiated.
   End Sub

End Class
JRS
sumber
3
Dan inilah sintaks untuk modul namespace: Imports <whatever>jika Anda memiliki impor apapun, Namespace MyCoolModule, Public Module MyCoolModule, <anggota tanpa Shared >, End Module, End Namespace.
Rory O'Kane
0

Modul baik untuk menyimpan enum dan beberapa variabel global, konstanta dan fungsi bersama. itu hal yang sangat bagus dan saya sering menggunakannya. Variabel yang dideklarasikan adalah acros yang terlihat seluruh proyek.

GGSoft
sumber
0

Anda harus menggunakan Modul (bukan Kelas) jika Anda membuat metode Extension. Di VB.NET saya tidak mengetahui opsi lain.

Menjadi resisten terhadap Modul sendiri, saya hanya menghabiskan beberapa jam tidak berharga mencoba untuk mencari tahu bagaimana menambahkan beberapa kode boilerplate untuk menyelesaikan rakitan tertanam dalam satu, hanya untuk mengetahui bahwa Sub New()(Modul) dan Shared Sub New()(Kelas) adalah setara. (Aku bahkan tidak tahu ada adalah sebuah callable Sub New()dalam Modul!)

Jadi saya hanya melempar EmbeddedAssembly.Loaddan AddHandler AppDomain.CurrentDomain.AssemblyResolvegaris di sana dan Bob menjadi paman saya.

Tambahan : Saya belum memeriksanya 100%, tetapi saya memiliki firasat yang Sub New()berjalan dalam urutan berbeda dalam Modul daripada Kelas, hanya berdasarkan fakta bahwa saya harus memindahkan beberapa deklarasi ke metode dalam dari luar untuk menghindari kesalahan.

SteveCinq
sumber