È accettabile definire un "modulo" e una "classe" all'interno di un singolo elemento .VB?

5

Esperimento:

Ho trovato che possibile è possibile definire sia un "Modulo" (Namespace?) sia una "Classe" (Namespace?) all'interno di un singolo elemento .Vb (Modulo ??).

Puoi provarlo a casa:

  • Crea un nuovo progetto di applicazione per console.
    * Un nuovo elemento .Vb denominato "Module1.Vb" viene automaticamente aggiunto al progetto.
  • Aggiungi un nuovo elemento Class .Vb facendo clic con il pulsante destro del mouse sul progetto in Esplora soluzioni > Aggiungi > Classe ...
  • Dai alla nuova classe il nome Test .
  • Visualizza il codice per "Test.Vb" e incolla quanto segue:
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

Visualizza il codice per il modulo 1 e incolla quanto segue:

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

Ora vai avanti e passa o esegui l'applicazione. Vedrai tutto funziona. Quindi, passiamo al ...

Carne della domanda

Questa pratica è accettabile? Potrebbe essere tecnicamente possibile - ma è una soluzione cattiva per ragioni che non conosco? (Sono un Mort e davvero non voglio prendere inconsapevolmente cattive pratiche di codifica)

Inizialmente avevo questo come metodo Private all'interno della definizione di classe come questa:

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

Ho deciso che sarebbe stato più pulito definire il ToConsole sub come metodo di estensione per Exception oggetti, ma è lì che ho incontrato dei problemi. Quando ho creato l'attributo Extension nello spazio dei nomi Class , ho ricevuto un errore del compilatore:

Extension methods can be defined only in modules.

Quindi, ho provato l'esperimento precedente e ho dichiarato un Module nello stesso elemento .VB in cui è definito il mio Class .
Come mostra l'esperimento sopra riportato, tutto questo si compila bene e funziona come previsto, ma mi piacerebbe sapere se questa è una buona idea oppure no, e perché?

Grazie per aver dedicato del tempo a leggere questo e ancora più grazie per il tempo impiegato a commentare o rispondere!

    
posta CBRF23 15.07.2015 - 16:11
fonte

2 risposte

2

In generale, l'idea di un Class o Module per file è qualcosa che ho notato per la prima volta in Java (credo che sia / era un requisito lì). C # ha continuato come suggerimento, e VB.NET probabilmente ha lo stesso suggerimento da qualche parte.

Tuttavia, poiché i progettisti di VB.NET hanno deciso che è possibile avere solo metodi di estensione in Modules , hai fornito un esempio in cui ha senso che un'altra unità di codice sia così strettamente correlata a un'altra Class da includilo nello stesso file.

Ovviamente, con il concetto di Partial di classi e moduli hai l'idea opposta di dividere singole unità su più file disponibili.

E a proposito di questo concetto normalmente significa che Module si chiamerà TestExtensions : -)

Al tuo "Namespace?" note nella tua domanda: VB.NET fornisce uno spazio dei nomi basato sul progetto per il tuo Modules e Classes , quindi le tue classi ora vengono chiamate ProjectNamespace.UnitName . Se hai fornito un

Namespace SomeNamespace
...
End Namespace

le unità incluse sarebbero denominate ProjectNamespace.SomeNamespace.UnitName .

Puoi anche avere più Namespaces in un file, e puoi sovrascrivere ProjectNamespace con Global. :

Namespace Global.TopLevelNamespace
...
End Namespace

Rileggendo la tua domanda e prendendo nota della nota "(Modulo?)", suppongo che tu stia effettivamente chiedendo quale sia il termine "formale" VB.NET per le unità di codice che includono Class e Module e il termine simile per un file di codice. Poiché il modulo di .NET è così spesso equivalente a un Assembly, la maggior parte delle persone potrebbe sapere cosa intendevi se si fa riferimento a unità di codice "Livello spazio dei nomi" come "moduli" e i file di origine sono solo "file". (Potrebbero esserci altri luoghi che danno nomi alternativi, ma ho basato questo su Introduzione di Microsoft ).

    
risposta data 22.07.2015 - 04:13
fonte
2

Come hai scoperto, il codice funziona bene indipendentemente dal file in cui lo hai inserito. Quindi si tratta dell'organizzazione ... dove metti le cose?

Quello che ho trovato è che la qualsiasi partenza dalle convenzioni "standard" rende molto difficile navigare attraverso una base di codice di qualsiasi dimensione significativa. Dici di avere questa piccola classe di aiuto, ma dove diavolo è? Lo metti in una soluzione diversa, e ho un riferimento ai metadati, ma dove l'hai messo effettivamente? A meno che tu non aderisca rigorosamente all'unico file per classe / interfaccia / qualsiasi cosa, ora mi hai costretto a fare una ricerca, e io ti vengo dietro con un coltello da intaglio.

Questo post di Overflow dello stack elenca alcune delle eccezioni in cui potrebbe avere senso interrompere questa regola:

  1. Classi parziali,
  2. Metodi di estensione,
  3. Enum che riguardano solo una singola classe, anche se in genere li inserisco nel proprio file.
risposta data 22.07.2015 - 04:45
fonte

Leggi altre domande sui tag