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

137

Является ли приемлемой практикой использование модулей вместо классов с помощью общих функций-членов в VB.NET?

Я стараюсь избегать Модулей, потому что они чувствуют, что оставшиеся остаются с Visual Basic 6.0 и, похоже, больше не подходят. С другой стороны, не существует большой разницы между использованием модуля и класса с использованием только общих членов. Это не так часто, что я действительно нуждаюсь в этом, но иногда бывают ситуации, когда они представляют собой простое решение.

Мне любопытно узнать, есть ли у вас какие-либо мнения или предпочтения так или иначе.

  • 10
    Одним из интересных моментов для модулей является то, что по умолчанию методы и функции, объявленные внутри, имеют уровень защиты модуля, что означает, что вы можете непреднамеренно сделать методы доступными, если вы забудете явно добавить Private . В классе уровень защиты по умолчанию является закрытым, что может привести к путанице, если вы не знаете об этом.
Теги:

9 ответов

172
Лучший ответ

Module являются эквивалентами VB классам С# static. Когда ваш класс предназначен исключительно для вспомогательных функций и методов расширения, и вы не хотите разрешить наследование и , используйте Module.

Кстати, использование Module не очень субъективно и не устарело. Действительно, вы должны использовать Module, когда это уместно. Сама .NET Framework делает это много раз (System.Linq.Enumerable, например). Чтобы объявить метод расширения, ему необходимо использовать Module s.

  • 6
    Совершенно верно, хотя я могу использовать закрытый конструктор для предотвращения создания экземпляров и модификатор NotInheritable. Немного страшнее старого модуля, но имеет тот же эффект. Спасибо за указатель на использование модулей в платформе; Я посмотрю на это.
  • 7
    Под капотом они просто скомпилированы в классы с атрибутом [StandardModule]. Кроме того, использование модуля вынуждает вас не иметь там ничего общего, что хорошо.
Показать ещё 4 комментария
24

Я думаю, что рекомендуется избегать модулей, если вы не вставляете их в отдельные пространства имен. Потому что в Intellisense методы в модулях будут видны повсюду в этом пространстве имен.

Итак, вместо ModuleName.MyMethod() вы получаете всплывающие окна MyMethod() в любом месте, и этот тип аннулирует инкапсуляцию. (по крайней мере, на уровне программирования).

Вот почему я всегда пытаюсь создать класс с общими методами, кажется намного лучше.

  • 4
    Согласен, сейчас я работаю над старой программой (вероятно, порт VB6 - VB.NET 1) с классами и модулями. Существуют сотни глобальных переменных, подпрограмм и функций примерно в десяти различных модулях, и это чертовски важно выяснить, откуда и как они были модифицированы.
21

Модули ни в коем случае не устарели и сильно используются на языке 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
  • 3
    Методы расширения ... еще одна замечательная функция, которую я всегда хочу использовать, но никогда не получаю - ну, это дает мне еще одну хорошую возможность. Я действительно немного разбираюсь в глобальной области видимости, и общедоступные методы, безусловно, могут быть удобными, но я чувствую себя немного странно из-за их чрезмерного использования. Во всяком случае, все ответы до сих пор говорят мне, что я не должен отклонять модули из-под контроля; Есть веские причины использовать их в правильных обстоятельствах.
8

Допустимо использовать Module. Module не используется для замены Class. Module выполняет свою собственную задачу. Цель Module заключается в использовании в качестве контейнера для

  • методы расширения,
  • которые не являются специфическими для любого Class, или
  • которые не подходят должным образом в любом Class.

Module не похож на Class, так как вы не можете

  • наследует от Module,
  • реализовать Interface с Module,
  • или создать экземпляр Module.

Все, что находится внутри Module, можно получить непосредственно в сборке Module без ссылки на Module по его имени. По умолчанию уровень доступа для Module равен Friend.

7

Классы

  • классы могут быть созданы как объекты
  • Данные объекта существуют отдельно для каждого экземпляра объекта.
  • классы могут реализовывать интерфейсы.
  • Члены, определенные в классе, находятся в пределах определенного экземпляра класса и существуют только для времени жизни объекта.
  • Чтобы получить доступ к членам класса вне класса, вы должны использовать полнофункциональные имена в формате 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
  • 2
    А вот синтаксис для модуля пространства имен: Imports <whatever> если у вас есть какой-либо импорт, Namespace MyCoolModule , Public Module MyCoolModule , <члены без Shared >, End Module , End Namespace .
0

Если вы создаете методы расширения, вы должны использовать модуль (а не класс). В VB.NET я не знаю другого варианта.

Будучи устойчивым к модулям самостоятельно, я просто потратил целую пару часов на то, чтобы выяснить, как добавить шаблонный код для разрешения встроенных сборок в одном, только чтобы узнать, что Sub New() (Module) и Shared Sub New() ( Класс) эквивалентны. (Я даже не знал, что в модуле есть Sub New())

Поэтому я просто бросил строки EmbeddedAssembly.Load и AddHandler AppDomain.CurrentDomain.AssemblyResolve там, и Боб стал моим дядей.

Добавление. Я еще не проверял его на 100%, но у меня есть подозрение, что Sub New() работает в другом порядке в модуле, чем в классе, просто потому, что Мне пришлось переместить некоторые объявления внутрь методов снаружи, чтобы избежать ошибок.

0

Модули отлично подходят для хранения перечислений и некоторых глобальных переменных, констант и общих функций. это очень хорошая вещь, и я часто использую ее. Объявленные переменные - это видимый acros весь проект.

-5

VB.NET эквивалент статичности Shared. Функция может быть такой:

Public Shared Sub AddCacheDataTable()
   Return whatever
End Sub

Ещё вопросы

Сообщество Overcoder
Наверх
Меню