Simon Edström
Simon Edström

Reputation: 6619

Passing arguments, does unboxing occur

What I have read, passing arguments is by default valuetypes. In my example the first function test1 takes a reference type and unbox, it will decrease the performance if I got this right. However I have never read that you do like test2 for increase performance.

So whats best practice?

public Main(){
    string test = "hello";
    test1(test); // Does this line perform a boxing? So it's not good for performance?
    test2(ref test); // Passing a reference as a reference
}

public string test1(string arg1) {
    return arg1;
}

public string test2(ref string arg1) {
    return arg1;
}

Upvotes: 2

Views: 219

Answers (2)

Marc Gravell
Marc Gravell

Reputation: 1063318

There is no boxing here at all; boxing is when a value type is treated as object or an interface (not including generics), for example:

int i = 1;
Foo(i); // the value of i is boxed
Bar(i); // the value of i is boxed
...
private void Foo(object obj) {...}
private void Bar(IConvertible obj) {...}

In your examples, a: there is no type conversion here, so no need to box, and b: string is a reference-type anyway, so there is no meaning of boxing a string.

Your test2 is actually showing "pass by reference", aka ref, which is completely unrelated to boxing - and indeed ref parameters must be an exact match, so there is never any boxing involved in a ref parameter (however, subsequent code could obtain the value from the reference and then box/unbox that)

Upvotes: 5

Jon Skeet
Jon Skeet

Reputation: 1502006

There's no boxing or unboxing involved at all here. string is a reference type - why would it be boxed? What would that even mean?

Even if you used int instead, there'd be no need for boxing, because there's no conversion of the value into an actual object.

I suspect your understanding of both boxing and parameter passing is flawed.

Boxing occurs when a value type value needs to be converted into an object, usually in order for it to be used as a variable (somewhere) of an interface or object type. So this boxes:

int value = 10;
Foo(value);

...

public void Foo(object x)
{
}

... but it wouldn't occur if Foo were changed such that the type of x were int instead.

The detailed rules on boxing become very complicated to state precisely and accurately, particularly where generics come in, but that's the basics.

Upvotes: 6

Related Questions