É aceitável definir um “módulo” e uma “classe” dentro de um único elemento .VB?

5

Experiência:

Eu descobri que é possível definir um "Módulo" (Namespace?) e uma "Class" (Namespace?) dentro de um único elemento .Vb (Module ??).

Você pode tentar isso em casa:

  • Criar um novo projeto de aplicativo de console.
    * Um novo elemento .Vb chamado "Module1.Vb" é automaticamente adicionado ao projeto.
  • Adicione um novo elemento Class .Vb clicando com o botão direito do mouse no projeto no Gerenciador de Soluções > Adicionar > Classe ...
  • Dê à nova turma o nome Test .
  • Visualize o código para "Test.Vb" e cole o seguinte:
Imports System.Runtime.CompilerServices


Module ExtensionsTest
    <Extension()>
    Public Sub ToConsole(ByVal Ex As Exception)
        Dim ForeColor As ConsoleColor
        Console.ForegroundColor = ConsoleColor.Red
        Console.WriteLine()
        Console.WriteLine("An unhandled exception has occurred!")
        Console.WriteLine(Ex.ToString)
        Console.ForegroundColor = ForeColor
    End Sub
End Module


Class Test
    Public Sub Test()
        Try
            Dim test As New Object
            test.SomeMethodDoesntExist()
        Catch ex As Exception
            ex.ToConsole()
        End Try
    End Sub
End Class

Veja o código do módulo 1 e cole o seguinte:

Module Module1
    Sub Main()
        Try
            Dim tester As New Test
            tester.Test()
        Catch ex As Exception
            MsgBox(ex.ToString)
        End Try
    End Sub
End Module

Agora vá em frente e percorra ou execute o aplicativo. Você verá tudo funciona. Então, vamos passar para o ...

Carne da pergunta

Esta prática é aceitável? Pode ser tecnicamente possível - mas é uma solução ruim por razões que eu não conheço? (Eu sou um Mort e realmente não quer pegar más práticas de codificação inconscientemente)

Eu originalmente tinha isso como um método Private dentro da definição de classe assim:

Imports System.Runtime.CompilerServices
Class Test
    Public Sub Test()
        Try
            Dim test As New Object
            test.SomeMethodDoesntExist()
        Catch ex As Exception
            ToConsole(ex)
        End Try
    End Sub

    Private Sub ToConsole(ByVal Ex As Exception)
        Dim ForeColor As ConsoleColor
        Console.ForegroundColor = ConsoleColor.Red
        Console.WriteLine()
        Console.WriteLine("An unhandled exception has occurred!")
        Console.WriteLine(Ex.ToString)
        Console.ForegroundColor = ForeColor
    End Sub
End Class

Eu decidi que seria mais limpo definir o ToConsole sub como um método de extensão para objetos Exception , mas foi aí que me deparei com problemas. Quando criei o atributo Extension dentro do namespace Class , recebi um erro do compilador:

Extension methods can be defined only in modules.

Então, tentei a experiência acima e declarei um Module dentro do mesmo elemento .VB onde meu Class está definido.
Como mostra o experimento acima, tudo isso compila bem e funciona como esperado, mas gostaria de saber se é uma boa ideia ou não e por quê?

Obrigado por reservar algum tempo para ler isto e ainda mais obrigado pelo tempo que levou para comentar ou responder!

    
por CBRF23 15.07.2015 / 16:11
fonte

2 respostas

2

Em geral, a ideia de um Class ou Module por arquivo é algo que notei pela primeira vez em Java (acredito que seja / foi um requisito lá). O C # continuou como uma sugestão, e o VB.NET provavelmente agora tem a mesma sugestão em algum lugar.

No entanto, como os designers do VB.NET decidiram que você só pode ter métodos de extensão em Modules , você forneceu um exemplo em que faz sentido que outra unidade de código esteja tão intimamente relacionada a outro Class incluí-lo no mesmo arquivo.

Claro que, com o conceito de Partial classes e módulos, você tem a ideia oposta de dividir unidades individuais em vários arquivos disponíveis também.

E BTW, esse conceito normalmente significa que Module seria nomeado TestExtensions : -)

Para o seu "namespace"? observa em sua pergunta: VB.NET fornece um namespace baseado em projeto para seus Modules e Classes , então suas classes agora são nomeadas ProjectNamespace.UnitName . Se você forneceu um

Namespace SomeNamespace
...
End Namespace

as unidades incluídas seriam nomeadas ProjectNamespace.SomeNamespace.UnitName .

Você também pode ter vários Namespaces em um arquivo e pode substituir o ProjectNamespace por Global. :

Namespace Global.TopLevelNamespace
...
End Namespace

Relendo sua pergunta e anotando também a nota "(Módulo?)", estou supondo que você está realmente perguntando qual é o termo "formal" do VB.NET para unidades de código que incluem Class e Module e o termo semelhante para um arquivo de código. Como o Módulo do .NET é tão frequentemente equivalente a uma Assembléia, a maioria das pessoas saberia o que você quis dizer se você se referiu a unidades de código "Namespace-level" como "módulos" e arquivos de origem são apenas "arquivos". (Pode haver outros locais que forneçam nomes alternativos, mas eu baseei isso em Introdução da Microsoft a>.)

    
por 22.07.2015 / 04:13
fonte
2

Como você descobriu, o código funciona bem, independentemente do arquivo em que você o insere. Então, tudo se resume à organização ... onde você colocará as coisas?

O que eu descobri é que qualquer saída das convenções "padrão" torna muito difícil navegar por uma base de código de tamanho significativo. Você diz que tem essa pequena classe de ajudante, mas onde diabos está? Você coloca em uma solução diferente, e eu tenho uma referência de metadados para ela, mas onde você colocou isso? A menos que você adira estritamente ao único arquivo por classe / interface / o que quer que seja, você agora me forçou a fazer uma pesquisa, e eu vou atrás de você com uma faca.

Esta publicação sobre estouro de pilha lista algumas das exceções nas quais pode ser útil quebrar essa regra:

  1. Classes parciais,
  2. Métodos de extensão
  3. Enums que pertencem apenas a uma única classe, embora eu ainda geralmente os coloque em seu próprio arquivo.
por 22.07.2015 / 04:45
fonte