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

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

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

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

Ответ 1

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

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

Ответ 2

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

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

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

Ответ 3

Модули ни в коем случае не устарели и сильно используются на языке 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

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

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

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

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

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

Ответ 5

Классы

  • классы могут быть созданы как объекты
  • Данные объекта существуют отдельно для каждого экземпляра объекта.
  • классы могут реализовывать интерфейсы.
  • Члены, определенные в классе, находятся в пределах определенного экземпляра класса и существуют только для времени жизни объекта.
  • Чтобы получить доступ к членам класса вне класса, вы должны использовать полнофункциональные имена в формате 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

Ответ 7

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

Ответ 8

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

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

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

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

Ответ 9

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

Public Shared Sub AddCacheDataTable()
   Return whatever
End Sub