Classes vs. módulos no VB.NET


157

É uma prática aceitável usar módulos em vez de classes com funções de membro compartilhado no VB.NET?

Eu costumo evitar os módulos, porque eles parecem restos do Visual Basic 6.0 e realmente não parecem mais se encaixar. Por outro lado, não parece haver muita diferença entre usar um módulo e uma classe apenas com membros compartilhados. Não é tão frequente que eu realmente tenha muita necessidade, mas às vezes há situações em que elas apresentam uma solução simples.

Estou curioso para saber se você tem alguma opinião ou preferência de uma forma ou de outra.


10
Um interessante sobre os módulos é que, por padrão, os métodos e funções declarados dentro têm o nível de proteção do módulo, o que significa que você pode inadvertidamente disponibilizar métodos disponíveis se esquecer de adicionar explicitamente o Privatequalificador. Em uma classe, o nível de proteção padrão é privado, o que pode ser um comportamento confuso, a menos que você esteja ciente disso.
yu_ominae 18/12/12

Respostas:


207

Modules são equivalentes de VB para staticclasses C # . Quando sua classe é projetada exclusivamente para funções auxiliares e métodos de extensão e você não deseja permitir herança e instanciação , use a Module.

A propósito, o uso Modulenão é realmente subjetivo e não é preterido . Na verdade, você deve usar um Modulequando for apropriado. O próprio .NET Framework faz isso várias vezes ( System.Linq.Enumerablepor exemplo). Para declarar um método de extensão, é necessário usar Modules.


7
Muito bem, embora eu possa usar um construtor privado para impedir a instanciação e o modificador NotInheritable. Um pouco mais feio que um módulo antigo simples, mas tem o mesmo efeito. Obrigado pelo ponteiro para o uso de Módulos no Framework; Eu vou investigar isso.
Tom Juergens

8
Sob o capô, eles são compilados apenas para classes com o atributo [StandardModule]. Além disso, o uso do Módulo obriga a não ter coisas não compartilhadas, o que é uma coisa boa.
Mehrdad Afshari

18
Módulos não são iguais às classes estáticas em C #. Os métodos em um módulo são efetivamente globais se estiverem em um espaço para nome importado.
21411 JaredPar

2
@ JaredPar: Minha redação provavelmente está ruim. Eu deveria ter dito homólogos do VB para classes estáticas em C #. A partir dessa afirmação, pretendia dizer que usar um módulo faz sentido onde você escreveria uma classe estática em C #.
Mehrdad Afshari

3
@Chiwda Consulte msdn.microsoft.com/en-us/library/bb384936.aspx : "Os métodos de extensão podem ser declarados apenas dentro dos módulos."
Mehrdad Afshari

34

Eu acho que é uma boa ideia continuar evitando os módulos, a menos que você os cole em namespaces separados. Porque, no Intellisense, os métodos nos módulos serão visíveis de qualquer lugar nesse espaço para nome.

Então, em vez de ModuleName.MyMethod()você acabar com MyMethod()pop - ups em qualquer lugar, isso invalida o encapsulamento. (pelo menos no nível de programação).

É por isso que eu sempre tento criar Classe com métodos compartilhados, parece muito melhor.


6
Concordo, estou trabalhando em um programa antigo no momento (provavelmente uma porta VB6 para VB.NET 1) com classes e módulos. Existem centenas de variáveis ​​globais, subs e funções em cerca de dez módulos diferentes, e é um inferno descobrir o que se originou onde e como foi modificado.
yu_ominae 18/12/12

ok, isso é muito antigo, mas relevante para a minha pergunta. Eu sou não um cara VB, mas eu tenho que trabalhar com ele. Estou tentando dividir uma grande classe (> 46.000 linhas) porque o IntelliSense / ReSharper simplesmente morre. Eu descobri que o uso de módulos e apenas extrair grandes blocos de funções em seu próprio módulo parece funcionar, mas estou pensando se devo atribuir a cada módulo seu próprio espaço de nome também. Isso seria necessário? ou seja, isso aceleraria o IntelliSense apenas com os módulos ou os Namespaces ajudariam mais?
codah 13/07

27

Os módulos não são obsoletos e são muito usados ​​na linguagem VB. É a única maneira, por exemplo, de implementar um método de extensão no VB.Net.

Há uma enorme diferença entre módulos e classes com membros estáticos. Qualquer método definido em um módulo é acessível globalmente, desde que o módulo esteja disponível no espaço para nome atual. De fato, um módulo permite definir métodos globais. Isso é algo que uma classe com apenas membros compartilhados não pode fazer.

Aqui está um exemplo rápido que eu uso muito ao escrever código VB que interage com interfaces COM brutas.

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
Métodos de extensão ... outro bom recurso que eu sempre pretendo usar, mas nunca realmente consegui - bem, isso me dá outra boa oportunidade. Eu entendo um pouco sobre o escopo global, e os métodos disponíveis globalmente podem certamente ser convenientes, mas me sinto um pouco enjoado com o uso excessivo deles. De qualquer forma, todas as respostas até agora me dizem que não devo descartar módulos de imediato; existem boas razões para usá-los nas circunstâncias certas.
Tom Juergens

12

É aceitável usar Module. Modulenão é usado como um substituto para Class. Moduleserve a seu próprio propósito. O objetivo Moduleé usar como recipiente para

  • métodos de extensão,
  • variáveis ​​que não são específicas de nenhuma Class, ou
  • variáveis ​​que não se encaixam corretamente em nenhuma Class.

Modulenão é como uma Classvez que você não pode

  • herdar de um Module,
  • implementar um Interfacecom um Module,
  • nem crie uma instância de a Module.

Qualquer coisa dentro de a Modulepode ser acessada diretamente dentro da Modulemontagem sem se referir ao Modulenome. Por padrão, o nível de acesso para a Moduleé Friend.


11

Aulas

  • classes podem ser instanciadas como objetos
  • Os dados do objeto existem separadamente para cada objeto instanciado.
  • classes podem implementar interfaces .
  • Os membros definidos em uma classe têm o escopo definido em uma instância específica da classe e existem apenas durante o tempo de vida do objeto .
  • Para acessar os membros da classe de fora de uma classe, você deve usar nomes totalmente qualificados no formato Object.Member .

Módulos

  • Os módulos não podem ser instanciados como objetos . Como existe apenas uma cópia dos dados de um módulo padrão, quando uma parte do seu programa altera uma variável pública em um módulo padrão, ela fica visível para todo o programa.
  • Membros declarados em um módulo são acessíveis ao público por padrão.
  • Pode ser acessado por qualquer código que possa acessar o módulo.
  • Isso significa que as variáveis ​​em um módulo padrão são efetivamente variáveis ​​globais porque são visíveis de qualquer lugar do seu projeto e existem durante toda a vida útil do programa.

6

Quando uma das minhas classes do VB.NET possui todos os membros compartilhados, eu a converto em um Módulo com um namespace correspondente (ou apropriado) ou torno a classe não herdável e não construtível:

Public NotInheritable Class MyClass1

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

End Class

3
E aqui está a sintaxe para um módulo namespaced: Imports <whatever>se você tiver quaisquer importações, Namespace MyCoolModule, Public Module MyCoolModule, <membros sem Shared >, End Module, End Namespace.
Rory O'Kane

0

Os módulos são bons para armazenar enumerações e algumas variáveis ​​globais, constantes e funções compartilhadas. é muito bom e eu costumo usá-lo. Variáveis ​​declaradas são visíveis em todo o projeto.


0

Você deve usar um módulo (em vez de uma classe) se estiver criando métodos de extensão. No VB.NET, não conheço outra opção.

Sendo resistente aos Módulos, passei algumas horas inúteis tentando descobrir como adicionar algum código padrão para resolver assemblies incorporados em um, apenas para descobrir que Sub New()(Módulo) e Shared Sub New()(Classe) são equivalentes. (Eu nem sabia que havia uma chamadaSub New() em um módulo!)

Então, eu só joguei o EmbeddedAssembly.Loade AddHandler AppDomain.CurrentDomain.AssemblyResolvelinhas lá e Bob tornou-se meu tio.

Adendo : Eu ainda não fiz o check-out 100%, mas tenho uma impressão que Sub New()é executada em uma ordem diferente em um Módulo e em uma Classe, apenas pelo fato de que eu tive que mover algumas declarações para métodos internos de fora para evitar erros.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.