Класи проти модулів у VB.NET


157

Чи вважається прийнятною практикою використання модулів замість класів із функціями спільних членів у VB.NET?

Я схиляюсь уникати модулів, тому що вони відчувають, що залишок залишився від Visual Basic 6.0 і насправді, здається, вже не вміщується. З іншого боку, не існує великої різниці між використанням модуля та класу лише із спільними членами. Не дуже часто мені дуже потрібна будь-яка, але іноді трапляються ситуації, коли вони представляють просте рішення.

Мені цікаво почути, чи є у вас якась думка чи уподобання так чи інакше.


10
Одне цікаве щодо модулів - це те, що за замовчуванням методи та функції, задекларовані всередині, мають рівень захисту модуля, а це означає, що ви можете ненавмисно зробити методи доступними, якщо забудете явно додати Privateкласифікатор. У класі рівень захисту за замовчуванням є приватним, що може заплутати поведінку, якщо ви цього не знаєте.
— yu_ominae

Відповіді:


207

Modules - аналоги VB staticкласам C # . Коли ваш клас призначений виключно для допоміжних функцій та методів розширення, і ви не хочете допускати успадкування та інстанціювання , ви використовуєте Module.

До речі, використання Moduleнасправді не є суб’єктивним і не застаріло . Дійсно, ви повинні використовувати, Moduleколи це підходить. Сам .NET Framework робить це багато разів ( System.Linq.Enumerableнаприклад,). Для оголошення методу розширення потрібно використовувати Modules.


7
Цілком правильно, хоча я можу використовувати приватний конструктор для запобігання інстанції та модифікатора NotInheritable. Трохи потворніше, ніж звичайний старий Модуль, але має той же ефект. Дякуємо за вказівник на використання модулів у рамках; Я розберуся в цьому.
— Том Юргенс

8
Під капотом вони просто компілюються в класи з атрибутом [StandardModule]. Крім того, використання модуля змушує вас не мати там неподілених речей, що добре.
— Мехрдад Афшарі

18
Модулі не такі, як статичні класи в C #. Методи в модулі є ефективно глобальними, якщо вони знаходяться в імпортованому просторі імен.
— JaredPar

2
@JaredPar: Моє формулювання, мабуть, погано. Я мав би сказати аналоги VB статичним класам C #. З цього твердження я мав намір сказати, що використання модуля має сенс, де ви пишете статичний клас у C #.
— Мехрдад Афшарі

3
@Chiwda Див. Msdn.microsoft.com/en-us/library/bb384936.aspx : "Методи розширення можна оголосити лише в межах модулів."
— Мехрдад Афшарі

34

Я думаю, що це гарна ідея уникати уникання модулів, якщо ви не вставите їх в окремі простори імен. Тому що в Intellisense методи модулів будуть видні звідусіль у цьому просторі імен.

Тож замість ModuleName.MyMethod()вас з'являться MyMethod()спливаючі місця в будь-якому місці, і цей вид приводить до недійсності інкапсуляції. (принаймні на рівні програмування).

Ось чому я завжди намагаюся створити Class із спільними методами, здається набагато кращим.


7
Погоджено, я зараз працюю над старою програмою (можливо, VB6 на VB.NET 1 порт) з класами та модулями. Існує сотні глобальних змінних, допоміжних функцій та функцій приблизно в десяти різних модулях, і це пекло з'ясувати, що виникло де і як воно змінилося.
— yu_ominae

ОК, це дуже старе, але відповідне на моє питання. Я не хлопець ВБ, але мені з цим треба працювати. Я намагаюся розбити великий клас (> 46 000 рядків), тому що IntelliSense / ReSharper просто гинуть. Я знайшов використання модулів і просто видобуток великих фрагментів функцій у їх власний Модуль, здається, працює, але мені цікаво, чи варто також кожному модулю надати власний простір імен. Це було б потрібно? тобто чи пришвидшить це IntelliSense лише за допомогою модулів, або простори імен допоможуть більше?
— кода

27

Модулі ні в якому разі не застаріли і активно використовуються мовою VB. Це єдиний спосіб, наприклад, реалізувати метод розширення у VB.Net.

Існує одна величезна різниця між модулями та класами зі статичними членами. Будь-який метод, визначений у модулі, є доступним у всьому світі, доки модуль доступний у поточному просторі імен. Фактично модуль дозволяє визначати глобальні методи. Це те, що не може зробити клас із лише спільними членами.

Ось короткий приклад того, що я багато використовую при написанні коду VB, який взаємодіє із сирими інтерфейсами COM.

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

4
Методи розширення ... ще одна прекрасна функція, яку я завжди маю на увазі використовувати, але ніколи насправді не обходжу - ну, це дає мені ще одну хорошу можливість. Я все-таки трохи розуміюсь на глобальному масштабі, і глобально доступні методи, безумовно, можуть бути зручними, але я відчуваю трохи непростого використання їх. У будь-якому випадку, всі відповіді, що йдуть досі, говорять мені, що я не повинен відхиляти модулі з рук; є вагомі причини використовувати їх у правильних обставинах.
— Том Юргенс

12

Його прийнятно використовувати Module. Moduleне використовується як заміна для Class. Moduleслужить власному призначенню. Мета Module- використовувати як контейнер для

  • методи розширення,
  • змінні, які не характерні для жодної Class, або
  • змінні, які не належать належним чином до жодної Class.

Moduleце не так, Classяк ви не можете

  • успадковувати від Module,
  • реалізувати за Interfaceдопомогою Module,
  • і не створювати примірник Module.

До всього, що знаходиться всередині a, Moduleможна отримати прямий доступ до Moduleзбірки, не посилаючись на Moduleйого ім'я. За замовчуванням рівень доступу для a Moduleє Friend.


11

Заняття

  • класи можна інстанціювати як об’єкти
  • Дані про об'єкти існують окремо для кожного об'єкта, що інстанціюється.
  • класи можуть реалізувати інтерфейси .
  • Учасники, визначені в класі, розміщуються в межах конкретного екземпляра класу і існують лише протягом життя об'єкта .
  • Для доступу до членів класу поза класом, ви повинні використовувати повністю кваліфіковані імена у форматі Object.Member .

Модулі

  • Модулі не можуть бути ідентифіковані як об'єкти , оскільки є лише одна копія даних стандартного модуля, коли одна частина вашої програми змінює загальнодоступну змінну в стандартний модуль, вона буде видима для всієї програми.
  • Учасники, задекларовані в модулі, за замовчуванням є загальнодоступними .
  • До нього можна отримати будь-який код, який може отримати доступ до модуля.
  • Це означає, що змінні в стандартному модулі - це фактично глобальні змінні, оскільки вони видимі з будь-якої точки вашого проекту, і вони існують протягом життя програми.

6

Коли в одному з моїх класів VB.NET є всі спільні члени, я або перетворюю його в Модуль з відповідним (або іншим чином відповідним) простором імен, або роблю клас не успадкованим і не конструктивним:

Public NotInheritable Class MyClass1

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

End Class

3
І ось синтаксис для модуля простору імен: Imports <whatever>якщо у вас є якийсь - або імпорт, Namespace MyCoolModule, Public Module MyCoolModule, <члени без Shared > End Module, End Namespace.
— Rory O'Kane

0

Модулі чудово підходять для зберігання переліків та деяких глобальних змінних, констант та загальних функцій. це дуже гарна річ, і я часто її використовую. Оголошені змінні є видимими для всього проекту.


0

Ви повинні використовувати модуль (а не клас), якщо ви створюєте методи розширення. У VB.NET мені не відомий інший варіант.

Будучи стійким до самих Модулів, я просто витратив нікчемну пару годин, намагаючись розробити, як додати якийсь код котлопластини для вирішення вбудованих вузлів в одне, тільки щоб з'ясувати, що Sub New()(Модуль) і Shared Sub New()(Клас) є рівнозначними. (Я навіть не знаю , що було викликане Sub New()в модулі!)

Так що я просто кинув EmbeddedAssembly.Loadі AddHandler AppDomain.CurrentDomain.AssemblyResolveлінію там і Боб став моїм дядьком.

Додаток : Я ще не перевірив це на 100%, але у мене є друк, який Sub New()працює в іншому порядку в Модулі, ніж Клас, просто йдучи через те, що мені довелося перенести деякі декларації до внутрішніх методів ззовні, щоб уникнути помилки.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.