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.str
...
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.my
- 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.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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?
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
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
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.
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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 ?