Passing Structures as parameters in

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


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 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.
Who is Participating?
Hi Yelnoc:
I would have agreed with Greg's remark about structures vs classes, but just yesterday I stumbled on the following paragraph in Rockford Lhotka's "Expert On on On - Visual Basic .NET Business Objects" (recommended reading!)

"The reason why Rule is a Structure instead of a Class is down to memory management. As our application runs, we can expect that business rules will be constantly broken and 'un-broken', resulting in the creation and destruction of Rule entities each time. There's a higher cost to creating and destroying an object that there is for a Structure, so we're minimizing this effect as far as we can"

Now do notice here that the author is talking about a process where he KNOWS there is going to be substantial activity of creation and destruction. I would assume you need hundreds if not thousands of these for the "minimizing effect" that he is talking about to be noticeable. In a situation where the passing of structures occurs once or twice at a time, I would not bother, and would use classes. You never know when you would want to encapsulate the data in myStruct with its own functionality!


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 ?
YelnocAuthor Commented:
>> 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:

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?

Cloud Class® Course: Microsoft Office 2010

This course will introduce you to the interfaces and features of Microsoft Office 2010 Word, Excel, PowerPoint, Outlook, and Access. You will learn about the features that are shared between all products in the Office suite, as well as the new features that are product specific.

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)
    End Sub

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

End Module
YelnocAuthor Commented:

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.
sorry I typed too quickly the struct is COPIED to pass byval ... this can be an expensive operation.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.