locked
Doubt on Structures and Arrays: Version 2: Pls help RRS feed

  • Question

  • Say, there is a small organization which is founded by two promoters “JAIDEEP” and “SHILPA”. They have hired 2 employees whose names are “Joy” and “Sougata”. Since it is a small organization each of the employees report to both the promoters.

     

    My aim to create a structure named EMPLOYEE with only two fields: Name and Reporting_Authority. The Reporting_Authority field will be an array and since each employee reports to both promoters, I want to initialize this array with the names of the two promoters “JAIDEEP” and “SHILPA”. The idea is that as and when we create an instance, we need to only assign the names. Since the reporting authorities are fixed for every employee, the values that were initialized should get attached to the instance being created automatically. Only the name field should be populated separately. For example when I create instance “e1” and assign “e1.Name=Sougata”, then assignment for {e1.reporting_authority(0)=”Jaideep”} and {e1.reporting_authority(1)=”Shilpa”} should happen automatically. The same thing repeats when instance e2 is created. To that end I wrote the following block of code but getting an error shown below:

    Public Structure employee
        Public name As String
        Public reporting_authority() As String
        Public Sub initialize()
            Dim reporting_authority() As String = {"Jaideep", "Shilpa"}
        End Sub
    End Structure
    
    Module Module1
    
        Sub Main()
            Dim e1, e2 As New employee
    
            e1.name = "Sougata" : e2.name = "Joy"
            Console.WriteLine($"Employee Name: {e1.name}")
            Console.WriteLine($"Reports to:")
            For Each item As String In e1.reporting_authority
                Console.WriteLine($"   {item}")
                'Expecting the reporting authority names to be attached directly to the instance e1 and be fetched here
            Next
            Console.WriteLine("------------------")
            Console.WriteLine($"Employee Name: {e2.name}")
            Console.WriteLine($"Reports to:")
            For Each item As String In e2.reporting_authority
                Console.WriteLine($"   {item}")
            Next
    
            Console.WriteLine("------------------")
            Console.ReadLine()
        End Sub
    
    End Module
    
    



    Question 1:
    I have to use the NEW keyword in the line "Dim e1,e2 as NEW employee" else I get an error. Why do I need to use the NEW keyword to instantiate a structure which is a value type data? I am under the impression that NEW is to be used for instantiating classes?

    Question 2: I am getting the following error when I run the code. Please help me with this:


    Request you guys to help me on this.

    Regards,

    Sougata


    Sougata Ghosh

    Saturday, December 15, 2018 1:02 PM

Answers

  •  I wrote the following block of code but getting an error shown below:

    Public Structure employee
        Public name As String
        Public reporting_authority() As String
        Public Sub initialize()
            Dim reporting_authority() As String = {"Jaideep", "Shilpa"}
        End Sub
    End Structure
    
    Module Module1
    
        Sub Main()
            Dim e1, e2 As New employee
    
            e1.name = "Sougata" : e2.name = "Joy"
            Console.WriteLine($"Employee Name: {e1.name}")
            Console.WriteLine($"Reports to:")
            For Each item As String In e1.reporting_authority
                Console.WriteLine($"   {item}")
                'Expecting the reporting authority names to be attached directly to the instance e1 and be fetched here
            Next
            Console.WriteLine("------------------")
            Console.WriteLine($"Employee Name: {e2.name}")
            Console.WriteLine($"Reports to:")
            For Each item As String In e2.reporting_authority
                Console.WriteLine($"   {item}")
            Next
    
            Console.WriteLine("------------------")
            Console.ReadLine()
        End Sub
    
    End Module
    


    Question 2: I am getting the following error when I run the code. Please help me with this:



    Make the changes indicated in Bold and marked with ' <<<<

    Public Structure employee
        Public name As String
        Public reporting_authority() As String
        Public Sub initialize()
            'Dim reporting_authority() As String = {"Jaideep", "Shilpa"}
            reporting_authority = {"Jaideep", "Shilpa"} ' <<<<
        End Sub
    End Structure
    
    Module Module1
    
        Sub Main()
            Dim e1, e2 As New employee
            e1.initialize() ' <<<<
            e2.initialize() ' <<<<
    
            e1.name = "Sougata" : e2.name = "Joy"
            Console.WriteLine($"Employee Name: {e1.name}")
            Console.WriteLine($"Reports to:")
            For Each item As String In e1.reporting_authority
                Console.WriteLine($"   {item}")
                'Expecting the reporting authority names to be attached directly to the instance e1 and be fetched here
            Next
            Console.WriteLine("------------------")
            Console.WriteLine($"Employee Name: {e2.name}")
            Console.WriteLine($"Reports to:")
            For Each item As String In e2.reporting_authority
                Console.WriteLine($"   {item}")
            Next
    
            Console.WriteLine("------------------")
            Console.ReadLine()
        End Sub
    
    End Module
    

    - Wayne

    • Proposed as answer by IronRazerz Sunday, December 16, 2018 1:26 AM
    • Marked as answer by sougata12 Sunday, December 16, 2018 6:02 AM
    Saturday, December 15, 2018 11:16 PM

All replies

  • Hi

    Trying to layout your needs, I came uo with this. I do use a Class instead of a Structure (there are reasons to avoid structures).

    This code seems to build a list of employees following your description.

    Option Strict On
    Option Explicit On
    Public Class Form1
      Dim ra() As String = {"Jaideep", "Shilpa"}
      Dim employees As New List(Of employee)
      Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    
        Dim a As New employee With {.name = "Sougata"}
        Dim b As New employee With {.name = "Joy"}
    
        employees.AddRange({a, b})
        ' here, you have a list of employees
        ' with correct Properties.
      End Sub
      Public Class employee
        Public name As String
        Public reporting_authority As New List(Of String)
        Sub New()
          reporting_authority = Form1.ra.ToList
        End Sub
      End Class
    End Class


    Regards Les, Livingston, Scotland

    Saturday, December 15, 2018 1:21 PM
  •  I wrote the following block of code but getting an error shown below:

    Public Structure employee
        Public name As String
        Public reporting_authority() As String
        Public Sub initialize()
            Dim reporting_authority() As String = {"Jaideep", "Shilpa"}
        End Sub
    End Structure
    
    Module Module1
    
        Sub Main()
            Dim e1, e2 As New employee
    
            e1.name = "Sougata" : e2.name = "Joy"
            Console.WriteLine($"Employee Name: {e1.name}")
            Console.WriteLine($"Reports to:")
            For Each item As String In e1.reporting_authority
                Console.WriteLine($"   {item}")
                'Expecting the reporting authority names to be attached directly to the instance e1 and be fetched here
            Next
            Console.WriteLine("------------------")
            Console.WriteLine($"Employee Name: {e2.name}")
            Console.WriteLine($"Reports to:")
            For Each item As String In e2.reporting_authority
                Console.WriteLine($"   {item}")
            Next
    
            Console.WriteLine("------------------")
            Console.ReadLine()
        End Sub
    
    End Module
    


    Question 2: I am getting the following error when I run the code. Please help me with this:



    Make the changes indicated in Bold and marked with ' <<<<

    Public Structure employee
        Public name As String
        Public reporting_authority() As String
        Public Sub initialize()
            'Dim reporting_authority() As String = {"Jaideep", "Shilpa"}
            reporting_authority = {"Jaideep", "Shilpa"} ' <<<<
        End Sub
    End Structure
    
    Module Module1
    
        Sub Main()
            Dim e1, e2 As New employee
            e1.initialize() ' <<<<
            e2.initialize() ' <<<<
    
            e1.name = "Sougata" : e2.name = "Joy"
            Console.WriteLine($"Employee Name: {e1.name}")
            Console.WriteLine($"Reports to:")
            For Each item As String In e1.reporting_authority
                Console.WriteLine($"   {item}")
                'Expecting the reporting authority names to be attached directly to the instance e1 and be fetched here
            Next
            Console.WriteLine("------------------")
            Console.WriteLine($"Employee Name: {e2.name}")
            Console.WriteLine($"Reports to:")
            For Each item As String In e2.reporting_authority
                Console.WriteLine($"   {item}")
            Next
    
            Console.WriteLine("------------------")
            Console.ReadLine()
        End Sub
    
    End Module
    

    - Wayne

    • Proposed as answer by IronRazerz Sunday, December 16, 2018 1:26 AM
    • Marked as answer by sougata12 Sunday, December 16, 2018 6:02 AM
    Saturday, December 15, 2018 11:16 PM
  •  As Wayne has suggested/shown,  you are not calling the 'initialize' sub of the structures to set the array values. You need to do that after you create the structures.  Using a Class instead of a Structure would be a much better way to go about doing this but,  my guess is that this is a class/homework assignment and you are suppose to use structures.

    If you say it can`t be done then i`ll try it

    • Edited by IronRazerz Sunday, December 16, 2018 1:35 AM
    Sunday, December 16, 2018 1:33 AM
  • @IronRAzerz and @ResLivings ...I know that class is a better way to handle such a problem but as Ironrazerz has mentioned I have to stick to Structures

    Sougata Ghosh

    Sunday, December 16, 2018 5:49 AM
  • @WayneAKing :

    Thanks. It works fine now. But one last question: When we create an instance of a structure I believe that there is no need for us to use the NEW keyword. Is my understanding correct?


    Sougata Ghosh

    Sunday, December 16, 2018 6:02 AM

  •  When we create an instance of a structure I believe that there is no need for us to use the NEW keyword. Is my understanding correct?

    You should be able to check that for yourself. Try changing:

    Dim e1, e2 As New employee

    to

    Dim e1, e2 As employee

    Rebuild and Run. It should do both without errors.

    - Wayne

    Sunday, December 16, 2018 6:14 AM
  • @WayneAking

    I did check it. And what I found is that when I am not using the NEW Keyword I get the following message, although it does not prevent it from running properly.....So that begs the question whether the absence of the NEW keyword may result in a compiling error for other cases?

    I am talking about the green swiggly line under "e1.initialize()" and "e2.initialize" in the picture. The program still works fine but then why is VB.net showing this message or in other words what is the role of the NEW keyword when we are instantiating the structure?


    Sougata Ghosh


    • Edited by sougata12 Sunday, December 16, 2018 6:23 AM
    Sunday, December 16, 2018 6:23 AM

  •  what is the role of the NEW keyword when we are instantiating the structure?



    See:

    Structures and Classes (Visual Basic)
    https://docs.microsoft.com/en-us/dotnet/visual-basic/programming-guide/language-features/data-types/structures-and-classes

    Selected quotes:

    "... structures do not require allocation of memory on the global heap."

    "Structures use stack allocation; classes use heap allocation."

    "A structure does not require a constructor; a class does."

    "Initialization. A structure variable implicitly includes an initialization
    of the elements using the structure's parameterless constructor. Therefore,
    Dim s As struct1 is equivalent to Dim s As struct1 = New struct1()."

    - Wayne

    • Proposed as answer by tommytwotrain Sunday, December 16, 2018 10:16 AM
    Sunday, December 16, 2018 6:39 AM
  • Ok. Will go through and many thanks.

    Sougata Ghosh

    Sunday, December 16, 2018 6:52 AM
  • So to relate back to the previous question, I believe this will still give a warning message:

       Dim s As struct1 is equivalent to Dim s As struct1 = New struct1()


    Similar to how this gets a warning:

       Dim s as string

    this does not:

       Dims s as string = ""

    Its not an object not declared warning its object is empty or null value. So there is just empty memory. WHen you add "" to s as string that puts something ??? in the memory for the string.

    So recall vb is by ref language so in the first case s has memory allocated but there is nothing in it, the memory null.

    You get a null ref error on this line:

        For Each item As String In e1.reporting_authority

    because reporting_authority is null.

    It is null because of the error in your declaration:

        Public Sub initialize()
            Dim reporting_authority() As String = {"Jaideep", "Shilpa"}
        End Sub

    where you should not use dim as that makes another sub routine level variable not the one defined at class level here:

        Public Structure employee
        Public name As String
        Public reporting_authority() As String
    ...


    So that was the original problem. You have two variables declared with the same name. One is declared class level. One is only declared in the sub and this is the one being used to fill the array. So you fill the wrong array even though to you it has the save name to vb it is just a reference to a different memory area.

    Wayne states the NEW contstructor part works automatically for a class, but not for a structure. In your first case you were making a constructor using the sub initialize (but in your original you did not call init). However with a class the NEW is called by the vb class when declared and with a structure it is not but you called it e1.initilize in (Wayne's) example which is almost the same thing a class does. That's what I was thinking in the other thread but was not sure.

    PS Plus the original declare was:

      Sub initialize()

    with no public. So vb had to assume something there as well. Not sure if that did anything.




    Sunday, December 16, 2018 10:11 AM

  •  When we create an instance of a structure I believe that there is no need for us to use the NEW keyword. Is my understanding correct?

    You should be able to check that for yourself. Try changing:

    Dim e1, e2 As New employee

    to

    Dim e1, e2 As employee

    Rebuild and Run. It should do both without errors.

    - Wayne

    Wayne,

    So, you mean for structures that use code as in your corrected example?

    With or without new is not the same for a normal class or for a structure like the original post?

    That is part of the question. How to use struc and also difference for a class. And also just the proper way to use both (my question too I don't know for sure).

    :)



    Sunday, December 16, 2018 10:55 AM
  • Thanks @tommytwotrain for the effort to write in detail. THE DIM part is fully clear. And for the last point you mentioned I think the absence of public/private for Sub Initialize() would not have made a difference. M saying this from general understanding, I will have to try it out later....

    Sougata Ghosh


    • Edited by sougata12 Sunday, December 16, 2018 6:29 PM
    Sunday, December 16, 2018 6:00 PM