none
Verify Scope Conclusions RRS feed

  • Question

  • I thought I had scope down pretty cold but I reach the following (surprising, to me) conclusions based on a project I am now building:

    1. A variable cannot be defined in the Application class that is available project-wide. If true, why not?
    2. A variable that is to be available project-wide, including in the Application class, can ONLY be defined in a Module.

    Any related comments are welcome.

    Tuesday, September 25, 2018 8:59 AM

All replies

  • There is another option which is a Singleton class which is available any place in a project.

    Public Class Example
        Private Shared _instance As Example
        Public Property DataTable As DataTable
        Public Demo As String
    
        <DebuggerStepThrough()>
        Protected Sub New()
            DataTable = New DataTable
        End Sub
        <DebuggerStepThrough()>
        Public Shared Function Instance() As Example
            If _Instance Is Nothing Then
                _Instance = New Example
            End If
            Return _Instance
        End Function
    End Class
    

    Simple usage to set a string

    Example.Instance().Demo = "Karen"

    Someplace else get the value

    Dim getValue = Example.Instance().Demo

    In regards to only defined in a static module, remember a module is a static class. Now you can create a class as follows that is available application scoped.

    Namespace My
        <ComponentModel.EditorBrowsable(ComponentModel.EditorBrowsableState.Never)>
        Partial Friend Class _UserInfo
            Public ReadOnly Property DomainName() As String
                Get
                    Return SystemInformation.UserDomainName
                End Get
            End Property
            Public ReadOnly Property UserNameExcludeDomain() As String
                Get
                    Return Replace(User.Name, DomainName & "\", "")
                End Get
            End Property
            Public ReadOnly Property LogOnServer() As String
                Get
                    Return Environment.GetEnvironmentVariable("LOGONSERVER")
                End Get
            End Property
        End Class
        <HideModuleName()>
        Friend Module KarenCustomUserObject
            Private instance As New ThreadSafeObjectProvider(Of _UserInfo)
            ReadOnly Property UserInfo() As _UserInfo
                Get
                    Return instance.GetInstance()
                End Get
            End Property
        End Module
    End Namespace

    Usage

    Console.WriteLine(My.UserInfo.UserNameExcludeDomain)

    Or use inheritance  and shadow the existing Network class

    Namespace My
        Partial Class MyComputer
            Public Shadows ReadOnly Property Network() As Networks
                Get
                    Return New Networks
                End Get
            End Property
        End Class
        Public  Class Networks
            Inherits Devices.Network
    
            Public Property Owner() As String = "Me"
    
        End Class
    End Namespace
    


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites

    Tuesday, September 25, 2018 10:13 AM
    Moderator
  • I thought I had scope down pretty cold but I reach the following (surprising, to me) conclusions based on a project I am now building:

    1. A variable cannot be defined in the Application class that is available project-wide. If true, why not?
    2. A variable that is to be available project-wide, including in the Application class, can ONLY be defined in a Module.

    Any related comments are welcome.

    1.  Not true.  You can define a field or property on the Application class and then access it anywhere using My.Application.VariableName

    Namespace My
        ' The following events are available for MyApplication:
        ' Startup: Raised when the application starts, before the startup form is created.
        ' Shutdown: Raised after all application forms are closed.  This event is not raised if the application terminates abnormally.
        ' UnhandledException: Raised if the application encounters an unhandled exception.
        ' StartupNextInstance: Raised when launching a single-instance application and the application is already active. 
        ' NetworkAvailabilityChanged: Raised when the network connection is connected or disconnected.
        Partial Friend Class MyApplication
            Public SomeVariable As String
        End Class
    End Namespace

        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            My.Application.SomeVariable = "testing"
        End Sub
    2. Also not true.  As you can see, the field SomeVariable is defined in the Application class.


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Tuesday, September 25, 2018 12:16 PM
    Moderator
  • You are right but I am left with a question.  Public (or Friend, the default) programming elements are supposed to be available within the assembly so why does your "SomeVariable" need the prefix "My.Application" for it to be available elsewhere in the project?
    Tuesday, September 25, 2018 9:20 PM
  • Public and Friend are accessibility modifiers.  Public means that the member is available from the object anywhere in the code that uses the object (be it the same project or another project that references the assembly containing the object).  Friend means that the member is only available within the same assembly where the object is declared.  But that member still has to be accessed from the object declaring it.

    In this case, My.Application is a class in a namespace.  So you must refer to the namespace and class instance in order to access the member.

    Encapsulating members within classes is core to Object Oriented Programming.  It results in cleaner and easier to maintain code.  The Module is a carry-over from procedural programming.  Public members in a module are not encapsulated in any other object and are therefore available to use directly by name anywhere in the program.  This is OK for constants but should generally be avoided for methods and properties/fields as it breaks a tenant of OOP and can result in messier code that is harder to debug and maintain.  


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Wednesday, September 26, 2018 12:30 PM
    Moderator