Link to home
Start Free TrialLog in
Avatar of Yelnoc
Yelnoc

asked on

Passing Structures as parameters in vb.net


Sometimes when programs become sufficiently large, I like to group my variables in Structures.  I consider this a good practice, some of my peers find it odd.

On a code review, I was challanged with the following questions, which I am unsure of:

Here's a synopsis:

Private Function myVeryLongFunctionName() As myStruct
  myVeryLongFunctionName.str1 = "123"
  ...
end function

or

Private Function myFunction() As myStruct
  dim myShortStruct as myStruct
  myShortStructName.str1 = "123"
  ...
  return myShortStructName
end function


- When a Function is populating and returning a structure, is there a performance penalty to Dim a local variable 'myLocalStruct' of type "myStruct" in the function and then use the Return statement to "Return myLocalStruct" at the end of the procedure, or, should one simply stick with using the Function name (with an 'AS myStruct' at the end of the function definition) and reference the structure members via 'myVeryLongFunctionName.myStructureMemeber' syntax throughout the function?  My function name is quite long, and thus it produces a bit more readable code to create a 'short name' and return it. However the strucuture is somewhat complex (containing XML Dom objects, other object pointers, and a variety of simple data types) and if there's overhead in the 'Return myLocalStructure' syntax, I'll forgo the added clarity of the local structure.  Bluring the picture a bit is my lack of understanding exactly when VB.net is passing pointers around (when copying or returning structures) and when it actually copies the contents of variables.

- Bonus:  I wanted to see the values in my structure, so I created a function to HTML format their values. When I did so, I passed the structure byVal into this function. Everywhere else in the code had been byRef. Suddenly, when debugging the program (a DLL business object for a web program), all the values in the "Locals" box where showing up as "error: cannot obtain value".  As far as I know, this was the case anywhere in my code, not while stepping into the newly creating function with the ByVal structure parameters.  Can anyone explain why "error: cannot obtain value" was showing up?

This is my first post. I intended to be generous with the points as I believe an answer that truely nails this one may prove challanging.
Avatar of gregoryyoung
gregoryyoung
Flag of Canada image


ok a few things ...

1) why create a struct instead of a class ? its a reference type so when you pass it byval it won't need to be copied ...
2) Using a class/struct as a return generally is a great idea !

I believe your error is due to the fact that it would actually need to be expanded i.e. it doesn't have a true "value" but is instead a container, what do you get when you place it in the watch window ?
ASKER CERTIFIED SOLUTION
Avatar of Dabas
Dabas
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Yelnoc
Yelnoc

ASKER

>> 1) why create a struct instead of a class ?

Unfortunately, I could not dig up an article that demonstrated UDT's superior performance over classes in VB6.  Got me hooked on UDTs, and then saved me when it came to in-house discussions on UDTs.  In my experience, UDTs/Structures often seem to be "guilty until proven innocient".

So, I dug up this on Structures: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dv_vstechart/html/vbtchUseClassStruct.asp

Good stuff. Answered many pieces of my question(s).  Here's a snip:

A structure can be preferable when:

1)You have a small amount of data and simply want the equivalent of the UDT (user-defined type) of previous versions of Visual Basic
2)You perform a large number of operations on each instance and would incur performance degradation with heap management
3)You have no need to inherit the structure or to specialize functionality among its instances
4)You do not box and unbox the structure
5)You are passing blittable data across a managed/unmanaged boundary

Item 3 says it all for me.

What I was getting at on the return value is this...  You set the return value of a function as a Structure.  If you then dim a variable to the structure type and return it (instead of using the function value itself) you've done yourself a disservice. The values or pointers from your DIMmed structure variable are copied into the return.

I'm still fairly concerned about  the "error: cannot obtain value".  What sin has one commited when passing a structure byVal to cause such pain?

as for #3 using sealed classes (not overridable) provides nearly identical functionality.

passing a structure byval causes the structure to be box/unboxed which violates #4 ...

what does your struct look like ?

in this code I can view members of the struct in the locals window...

Module Module1

    Structure test
        Public i As Integer
        Public j As Integer
    End Structure
    Sub bar(ByVal i As test)
        Console.WriteLine("foo")
    End Sub


    Sub Main()
        Dim foo As test
        foo.i = 12
        foo.j = 1
        bar(foo)
    End Sub

End Module
Avatar of Yelnoc

ASKER

From http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dv_vstechart/html/vbtchUseClassStruct.asp

Boxed Value Types
If you define a value type but subsequently treat it as an object, it must be boxed, or converted to type Object. The common language runtime boxes a value type instance by making a copy of it, embedding it in a newly allocated object, and storing pointers to its type information in the metadata.

You treat a structure as an object if you assign it to an Object variable or pass it to a procedure that takes an Object argument. If you do this, the common language runtime must box it and often unbox it, as well as manage it on the heap. This kind of treatment can make a structure considerably less efficient than if you had created it as a class in the first place

----------------------

"passing a structure byval causes the structure to be box/unboxed which violates #4" ????  I bet you're right, but I'm not seeing it based on what I read above.  

I could not reproduce with a quick code sample. Sending actual code would take some work as it is so dependent on abstracted XML objects and other interal framework code.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial