?
Solved

ByRef usage?

Posted on 2012-09-15
18
Medium Priority
?
810 Views
Last Modified: 2012-09-25
Hi,

Are there any documents or articles talking about .NET discouraging the use of ByRef?

If I have a custom class, should not I pass the instance of that class to a method as ByRef parameter value?
0
Comment
Question by:dkim18
  • 8
  • 5
  • 2
  • +3
18 Comments
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 38402458
It depends on your system and requirements. Passing by reference is often better in terms of performance because you are not passing the entire set of data to the method; rather you only passing a reference. In this way, both the caller and the callee see the same object in memory. This behavior can cause confusion for programmers who don't fully understand working with references as well as make it difficult to code parallel code.
0
 
LVL 40

Assisted Solution

by:Jacques Bourgeois (James Burger)
Jacques Bourgeois (James Burger) earned 668 total points
ID: 38402558
An object variable based on a class (also called a Reference object) is a pointer. So, no matter if you pass it ByVal (a copy of the pointer) or ByRef (the pointer itself), the routine that is called is always working on the same memory space. Since both the caller and the callee see the same memory space, so the same object in memory.

Lookup the documentation for "Differences Between Passing an Argument By Value and By Reference". For a reference type, when passing ByVal "The procedure cannot change the variable but can change members of the instance to which it points.". The pointer to the object is the value being passed to the procedure, not the object.

The difference between ByRef and ByVal comes into play only for Value objects, that is the basic types (Integer, String and so on) and structures (small objects such as Size, represented by 3 blocks glued together in IntelliSense).

The idea that "passing by reference is often better in terms of performance" is completely wrong. It comes from the VB6 era. The reality in .NET is quite the reverse, because memory is not handled the same way. The notion of managed code did not exist in VB6, but it is everywhere in .NET.

If you pass a reference object (based on a class), the difference between ByVal and ByRef is minimal. With ByVal, you are not passing a copy of the object, but only a copy of the pointer.

However, if you pass a value object (the majority of parameters are Integers, String, Date and the sorts), you involve a procedure called boxing / unboxing (look up boxing in the documentation) that brings quite a penalty on performance.
0
 
LVL 75

Assisted Solution

by:käµfm³d 👽
käµfm³d   👽 earned 668 total points
ID: 38402572
@JamesBurger
The idea that "passing by reference is often better in terms of performance" is completely wrong.
If you are going to quote me, then at least do me the courtesy of quoting me in the entirety = )

I quantified under what circumstances my comment would hold. To my knowledge, any language which performs by-value and by-reference passing is going to be better performing when passing references than passing values (disregarding parallel processing). The management of memory has little to do with whether or not a copy of data or a pointer to existing data is used. A copy is going to (typically) have more overhead than working with existing data. If you have a source to cite for the assertion that reference types are not more efficient in terms of passing large data structures, then I would would welcome the information.

There is indeed a difference in passing a reference type ByVal or ByRef. If you pass a reference ByRef, then within the method if you New a new object and assign it to the parameter, then the reference outside of the method sees the new object. On the contrary, if you pass a reference ByVal, creating a new object with New and assigning it to the ByVal parameter means the parameter is now pointing to an object which is completely different than that which is pointed to outside of the method.

For example:

Module Module1

    Sub Main()

        Dim theByVal As New Test() With {.AProperty = "Hello World!"}
        Dim theByRef As New Test() With {.AProperty = "Hello World!"}

        [ByVal](theByVal)
        [ByRef](theByRef)

        Console.WriteLine(theByVal.AProperty)
        Console.WriteLine(theByRef.AProperty)

    End Sub

    Sub [ByVal](ByVal p As Test)

        p = New Test()
        p.AProperty = "ByVal"

    End Sub

    Sub [ByRef](ByRef p As Test)

        p = New Test()
        p.AProperty = "ByRef"

    End Sub

End Module

Public Class Test
    Public Property AProperty As String
End Class

Open in new window


Now I do agree that most often any performance benefit will probably not be noticeable, but as I mentioned previously, it is dependent on the system. Many large objects passed in a tight loop would perform better as ByRef than as ByVal. There are, however, situations where a ByVal is what you need because your logic does need to operate on a copy.
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 38402573
I notice that you updated your comment prior to my post. My comment is in reference to the original comment you had  : )
0
 
LVL 55

Assisted Solution

by:Jaime Olivares
Jaime Olivares earned 332 total points
ID: 38402581
You should not use byref until you specifically need it. There are really few reasons to do it:
- You are passing a value type and want to affect the source variable inside the target function
- You are passing a reference type, and want the reference to be changed inside the target function
Performance is not the intent of this keyword, but behavior.
I develop large applications and almost never use ByRef (just 'ref' in C#)
0
 
LVL 5

Expert Comment

by:sameer_goyal
ID: 38402593
Well, ByVal and ByRef, are relevant to 'value types' like int, char, float and are basically overkill and irrelevant if used with 'reference types' like StringBuilder, SqlConnection, etc

Reason?

With reference types, when you pass them around in methods, they are already passed 'ByRef'. meaning that the called method, can actually effect changes to the member attributes or properties inside the ref types passed to it as parameters.

However, if you don't want the method called to impact any of the member attributes or properties of the passed ref type parameter, pass them using 'ByVal'

Similarly, 'ByVal' has no significance when value types are passed around as parameters to methods since by default, they are passed as 'ByVal'

But if you want, the called method to effect changes or updates to the value type parameters being passed, you should use 'ByRef'

I don't thing there is performance penalty in either of the case.

Does it help.

You can refer to MSDN on this link

http://msdn.microsoft.com/en-us/library/ddck1z30(v=vs.71).aspx
0
 
LVL 12

Assisted Solution

by:Mohamed Abowarda
Mohamed Abowarda earned 332 total points
ID: 38403365
Here is a quick example:
    Sub Main()
        Dim var As Integer = 0
        DoSomethingByVal(var)
        MsgBox("ByVal can't change the variables we pass. var = " & var)
        DoSomethingByRef(var)
        MsgBox("ByRef CAN change the variables we pass. var = " & var)
    End Sub

    Public Sub DoSomethingByRef(ByRef var As Integer)
        var = 10
    End Sub

    Public Sub DoSomethingByVal(ByVal var As Integer)
        var = 10
    End Sub

Open in new window


Most of the time you should use the default one which is ByVal, however, in some cases when you need that the function change the passed variable, you will have to use ByRef instead to accomplish that.
0
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 38403588
After some further thought on the matter, and after reading some of the recent comments, I think I focused more on the concepts of passing by value and passing by reference rather than the actual keywords ByVal and ByRef as they pertain to .NET. For that I will rescind my first comment as it can be cause for confusion.
0
 
LVL 40
ID: 38403638
A lot of discussion for a very simple question.

If I have a custom class, should not I pass the instance of that class to a method as ByRef parameter value?

If what you want to do is to use a class instance and/or modify it properties, it makes no difference whether you pass it ByVal or ByRef.

The convention and usually the best way to do that is ByVal because of the boxing and unboxing that can happen when passing some types of object ByRef, although it does not come into play when the object is an instance of a class.
0
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 38405587
@JamesBurger

Please cite a source for the following assertion:

...because of the boxing and unboxing that can happen when passing some types of object ByRef...
0
 
LVL 40
ID: 38405947
I learned of the mechanism at a Microsoft DevDays a few years ago, and their demonstration then was very clear.

I am however unable to find something very definitive. A search on "boxing unboxing" turns on a lot of hits, but at first sight, none is complete. You have to put things together from many references.

Most of the interesting pages deal with C# because C# programmers often have a background in C and understand the concepts of memory management through the stack an the heap. These are involved in the operation because value objects (structures) are stored on the stack while reference objects (classes) are handled in the heap).

This one for VB (http://msmvps.com/blogs/joacim/archive/2009/08/31/boxing-and-unboxing-in-net.aspx) does the same thing as almost all the other ones, it deals with ways to box and unbox yourself and does not associate the feature with ByRef.

This one from MSDN(http://msdn.microsoft.com/en-us/library/cc586700.aspx) indicates that boxing is implicitely used when passing parameters by reference.

And since the thing is a CLR feature, second sentence from (http://msdn.microsoft.com/en-us/library/yz2be5wk.aspx) indicates that it happens in all the .NET languages. This was very clear at the DevDays. Even COBOL.NET has it.
0
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 38406159
The reason I ask is because of the 4th sentence of the Note here:  http://msdn.microsoft.com/en-us/library/14akc2c7.aspx

There is no boxing of a value type when it is passed by reference.

Admittedly, a C# link, but my understanding is that the ref keyword is the equivalent of using ByRef in VB.NET.
0
 

Author Comment

by:dkim18
ID: 38406350
It is a little confusing.

JamesBurger is saying it doesn't matter which to use:

If what you want to do is to use a class instance and/or modify it properties, it makes no difference whether you pass it ByVal or ByRef.

If you pass a reference object (based on a class), the difference between ByVal and ByRef is minimal. With ByVal, you are not passing a copy of the object, but only a copy of the pointer.

I didn't really think of this in C# an Java.

It seems most of you are saying that I need to use the ByRef if I want to modify object properties.
Is that right?
0
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 38406366
It seems most of you are saying that I need to use the ByRef if I want to modify object properties.
Is that right?
No, not quite. If you want to modify the properties only, then it does not matter if you use ByRef or ByVa. If you want to modify the properties and the variable itself, then use ByRef. (See my "New" example or Medo3337's example above to see what we mean when we say "modify the variable".)
0
 
LVL 40

Assisted Solution

by:Jacques Bourgeois (James Burger)
Jacques Bourgeois (James Burger) earned 668 total points
ID: 38406520
@kaufmed

There is a contradiction between the page you are referencing and mine. Both are from Microsoft. Who knows.

I can only remember the demonstration at the DevDays, and it was with Visual Basic. A method receiving an variable was called repetitively inside of a loop. We were told that this involved boxing and caused a penalty hit.

The purpose of the demonstration was to show us a way to prevent this by boxing the variable implicitely before entering the loop, that is putting it in an Object variable and using the Object instead of the Integer in the loop. The difference was significative.

Naturally, if it is a one time thing, you won't feel it. But in the loop, it made quite a difference, although I do not remember the ratio.

In my book, if a choice between 2 techniques usually makes not difference on performance, but one does from time to time, I used that last one all the time, so I won't have to eventually have to check my code for performance problems. This is why ByRef is an exception in my mind.

If we come back to the TryParse discussed a few days ago, you always convert a variable only once. There is no reason to convert the same variable repetitively in a loop. Thus the decision of using a ByRef parameter made sense.
0
 

Author Comment

by:dkim18
ID: 38406541
I apologize in advance if I am not understanding you in first place.


can you explain again what you mean properties and variable?
Are you talking about Property and Field variables?
0
 
LVL 40
ID: 38406666
Variables are those things you declare with Dim:

Dim x As Integer
x=10

Properties are those values you can call on objects, that are shown by a little hand holding a piece of paper in the lists that open automatically on the screen in Visual Studio 2010 and less, and that you call with the following syntax:

myTextBox.Text = "foo"
myLabel.Width = 100

Fields are something you do not encounter often. They are in someway a combination variable/property. You use them as if they were properties, but in fact they are variables declared in the class or structue that define the object. In the IntelliSense lists of Visual Studio 2010 and less, they are shown with little blue boxes.
0
 
LVL 75

Accepted Solution

by:
käµfm³d   👽 earned 668 total points
ID: 38407523
...and you can modify either properties or variables outside of the class itself so long as they are defined as public (or perhaps internal or protected, but let's not over-complicate that issue just yet).

When I said, "If you want to modify the properties and the variable itself," I was referring to this:

Screenthot
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Many of us here at EE write code. Many of us write exceptional code; just as many of us write exception-prone code. As we all should know, exceptions are a mechanism for handling errors which are typically out of our control. From database errors, t…
Today I had a very interesting conundrum that had to get solved quickly. Needless to say, it wasn't resolved quickly because when we needed it we were very rushed, but as soon as the conference call was over and I took a step back I saw the correct …
Loops Section Overview
When cloud platforms entered the scene, users and companies jumped on board to take advantage of the many benefits, like the ability to work and connect with company information from various locations. What many didn't foresee was the increased risk…

571 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question