Классы против модулей в 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