0

I have some void methods which are static.

Is it better to pass variables by reference or by value, because I'm passing large amount of text into these variables :

public static void renderText(ref StringBuilder build)
{
  //Do your job.
}

So could someone explain me, what happens when I send a reference of StringBuilder, does it only access this StringBuilder? (It does not copy it right!).

And just in case I'm not changing the value or any other property of input arguments into methods.

So, in this cases where variables are huge enough and not manipulated, should I always send the reference of it, and if yes does it interfere with something?

khellang
  • 17,550
  • 6
  • 64
  • 84
Rosmarine Popcorn
  • 10,761
  • 11
  • 59
  • 89
  • possible duplicate of [Does it make sense to pass a "reference type" to a method as a parameter with 'ref' key?](http://stackoverflow.com/questions/5960778/does-it-make-sense-to-pass-a-reference-type-to-a-method-as-a-parameter-with-re) – H H Sep 13 '11 at 07:40
  • 1
    You do know that passing by reference is a lot faster if you have to do a lot of work with the parameter, or in your case, put a large amount of Text into it. This is because the parameter doesn't get copied if you pass it by reference. – ThaMe90 Sep 13 '11 at 07:40
  • Or [should I use “ref” to pass a collection (e.g. List) by reference to a method?](http://stackoverflow.com/q/3473552/60761) – H H Sep 13 '11 at 07:41
  • 2
    @ThaMe: the only thing that gets copied if you pass a reference type "by value" (without ref) is the reference (pointer). This is a constant size (Ptr sized) regardless of the size of the object. – chrisaut Sep 13 '11 at 07:46
  • And thus if you need to do heavy calculations on the parameter you will do it on the object pointed to by the pointer. If you did the operations on the object you passed by value, the method get's a local copy of the value, thus using more memory. – ThaMe90 Sep 13 '11 at 07:50
  • @thame, see http://stackoverflow.com/questions/7171842/does-passing-reference-types-using-ref-save-memory/7171858#7171858 – H H Sep 13 '11 at 07:57
  • Hmmm, Okay, it seems my understanding of passing by reference in C# is not what it should be then. Thanks for pointing that out though. – ThaMe90 Sep 13 '11 at 08:04

4 Answers4

3

Take a look at the following article by Jon Skeet in which he thoroughly explains the difference between passing by reference or by value.

Parameter passing in C#

or this blog post which illustrates the former article:

http://rapidapplicationdevelopment.blogspot.com/2007/01/parameter-passing-in-c.html

The last article actually uses the StringBuilder type in its examples, so you can clearly see what's going on in your case. If you pass in the StringBuilder type by reference you'll get this:

Reference type passed by reference:

enter image description here

Christophe Geers
  • 8,564
  • 3
  • 37
  • 53
2

As long as you're dealing with reference types (classes, which StringBuilder and String are), there's rarely a point in passing them by reference since no copy will be made anyways.

Lucero
  • 59,176
  • 9
  • 122
  • 152
0

Non-value types are always passed by reference. The purpose of ref keyword is to let you change the reference to the object inside the method.

You misunderstood the arguments passing completely. Read this article.

Artem Koshelev
  • 10,548
  • 4
  • 36
  • 68
  • 1
    There is, however, still a difference when passing a reference type by ref. – Jonathan Dickinson Sep 13 '11 at 07:37
  • @Artem i know that ,not kidding ,but i thought i could use pas by ref for this purpose .It would be tricky – Rosmarine Popcorn Sep 13 '11 at 07:41
  • No, reference type arguments are still passed by value by default. The value is a reference, that's all. Calling that "pass by reference" muddies the waters. See http://pobox.com/~skeet/csharp/parameters.html – Jon Skeet Sep 13 '11 at 07:44
  • Thanks Jon, I will use “by value of reference” from this moment :) – Artem Koshelev Sep 13 '11 at 07:49
  • 1
    @Jon, old discussion but (functionally) the instance of the reference type is passed by reference. It's just the reference that's passed by value. Funny we still haven't a good vocabulary to express this. – H H Sep 13 '11 at 08:01
  • @Henk: There's perfectly good vocabulary for it: the value of the argument is a reference. That value is copied - passed by value. Pass by reference involves all kinds of different things - lvalues and the like. As soon as you start talking about an *instance* being passed, that raises problems such as which instance is being passed when the value is null. Basically everything is *much* simpler when you separate "reference value" from "pass by reference" as separate concepts. – Jon Skeet Sep 13 '11 at 08:27
0

Passing arguments by value

By default, arguments in C# are passed by value. This means a copy of the value is created when passed to the method:

class Test
{
    static void Foo(int p)
    {
        p = p + 1;             // Increment p by one.
        Console.WriteLine(p);  // Write p to screen.
    } 

    static void Main()
    {
        int x = 8;            
        Foo(x);               // Make a copy of x.
        Console.WriteLine(x); // x will still be 8.
    }
}

Assigning p a new value does not change the contents of variable x, because p and x reside in different memory locations.

Passing a reference-tupe argument by value copies the reference, but not the object. An example in the case of string builder; here Foo sees the same StringBuilder object that main instantiated, but has an independent reference to it. So StrBuild and fooStrBuild are seperate variables that reference the same StringBuilder object:

class Test
{
    static void Foo(StringBuilder fooStrBuild)
    {
        fooStrBuild.Append("testing");            
        fooStrBuild = null;
    } 

    static void Main()
    {
        StringBuilder StrBuild = new StringBuilder();
        Foo(strBuild);
        Console.WriteLine(StrBuild.ToString()); // "testing"
    }
}

Because fooStrBuild is a copy of a reference changing its value does not change StrBuild.

Pass by reference

In the following, p and x refer to the same memory locations:

class Test
{
    static void Foo(ref int p)
    {
        p = p + 1;             // Increment p by one.
        Console.WriteLine(p);  // Write p to screen.
    } 

    static void Main()
    {
        int x = 8;            
        Foo(ref x);           // Make a copy of x.
        Console.WriteLine(x); // x is now 9.
    }
}

hence the value of p is changed.

Hope this helps.

MoonKnight
  • 23,214
  • 40
  • 145
  • 277