470,590 Members | 2,249 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 470,590 developers. It's quick & easy.

Passing by reference twice

If I am passing a variable by reference to another routine by reference, do
I need to dereference first?

string testString;
....

FirstSub(ref firstString)
{
HandleString(ref firstString); //do I need to de
reference here or just pass theString without the "ref"
}
void HandleString(ref theString)
{
Console.WriteLine(thestring);
}
Apr 18 '06 #1
22 3192
"tshad" <ts**********@ftsolutions.com> wrote in message
news:Oc**************@TK2MSFTNGP05.phx.gbl...
If I am passing a variable by reference to another routine by reference,
do I need to dereference first?

string testString;
...

FirstSub(ref firstString)
{
HandleString(ref firstString); //do I need to de
reference here or just pass theString without the "ref"
}
void HandleString(ref theString)
{
Console.WriteLine(thestring);
}
No, but why pass it a ref?


Apr 18 '06 #2
Because I am building the string in another function which can get fairly
large and I don't want to pass the actual string which will get very large.

It does seem to work now and I am not sure what I was doing that was causing
the problem. The example actually work.

I am curious as to why it work, however.

If I have testString and I pass it as a reference to FirstSub, then it has
the reference to testString (not the string itself). When I pass it to
HandleString, aren't I passing a reference to a reference of testString?

If that is the case, how does HandleString handle it correctly?

Thanks,

Tom

"Michael C" <no****@nospam.com> wrote in message
news:u4**************@TK2MSFTNGP03.phx.gbl...
"tshad" <ts**********@ftsolutions.com> wrote in message
news:Oc**************@TK2MSFTNGP05.phx.gbl...
If I am passing a variable by reference to another routine by reference,
do I need to dereference first?

string testString;
...
FirstSub(ref testString);

void FirstSub(ref firstString) {
HandleString(ref firstString); //do I need to de
reference here or just pass theString without the "ref"
}
void HandleString(ref theString)
{
Console.WriteLine(thestring);
}


No, but why pass it a ref?



Apr 18 '06 #3
"tshad" <ts**********@ftsolutions.com> wrote in message
news:Ol**************@TK2MSFTNGP02.phx.gbl...
Because I am building the string in another function which can get fairly
large and I don't want to pass the actual string which will get very
large.
C# doesn't copy the entire string when passing it by value. It's a reference
type so only a pointer to it will be passed anyway. You only need to pass a
reference if you want to modify the string.
If that is the case, how does HandleString handle it correctly?


It probably just passes on the pointer it has.

Michael
Apr 18 '06 #4

"Michael C" <no****@nospam.com> wrote in message
news:uT*************@TK2MSFTNGP02.phx.gbl...
"tshad" <ts**********@ftsolutions.com> wrote in message
news:Ol**************@TK2MSFTNGP02.phx.gbl...
Because I am building the string in another function which can get fairly
large and I don't want to pass the actual string which will get very
large.
C# doesn't copy the entire string when passing it by value. It's a
reference type so only a pointer to it will be passed anyway. You only
need to pass a reference if you want to modify the string.


As strings are immutable in C#, in neither case (ref or not) is it possible
for you to modify a string.
If it's passed by ref, you can modify the reference that the caller has
passed to a new string, but you still can not change the existing string.
If you want to actually "modify a string", pass a StringBuilder or char[]
instead.

m
If that is the case, how does HandleString handle it correctly?


It probably just passes on the pointer it has.

Michael

Apr 18 '06 #5
Hi,

In .NET, String is a Reference Type. It is allocated on the heap, and
the variable that you've declared (testString) contains it's address (a
pointer to it). This means that you will always be passing some form of
reference to the instance rather than the instance itself, whether you
pass the testString variable by ref or by value -- so I'm not sure that
you need to put the 'ref' bit in.

If testString was a Value Type, then adding ref would give you the same
behaviour as when you pass a Reference Type by value -- it would allow
you to manipulate the same instance of the Value Type.

In the code in your post, would I think that all of the variables will
be pointing to the same instance of your String. I suspect you could
drop the ref and all would be ok.

Cheers, Mart.

Apr 18 '06 #6
"Mike" <vi********@yahoo.com> wrote in message
news:uT**************@TK2MSFTNGP05.phx.gbl...
As strings are immutable in C#, in neither case (ref or not) is it
possible for you to modify a string.
If it's passed by ref, you can modify the reference that the caller has
passed to a new string, but you still can not change the existing string.
If you want to actually "modify a string", pass a StringBuilder or char[]
instead.


That's true, although from outside the function the appearance is the string
has been modified. This is the same as any time you use a string as you're
always getting a reference to a new string, so the case of using the
function is nothing special.

Michael
Apr 18 '06 #7
> Because I am building the string in another function which can get fairly
large and I don't want to pass the actual string which will get very large.
A string is a reference type, so whenever you pass it, it doesn't get
copied on the stack anyway. You're always passing a reference.

The only question is whether you want to replace the string you passed
with a different string, in which case you need the "ref" keyword. What
"ref" says is that you may want to change the variable that contains a
reference (pointer) to the string to contain a reference (pointer) to a
different string upon return.

So, if HandleString changes the string to which theString points, and
wants the caller to FirstSub to receive the change, then you need
"ref". Something like this:

void FirstSub(ref string theString)
{
...
HandleString(ref theString);
...
}

void HandleString(ref string aString)
{
aString = String.Format(...);
}

Then any caller to FirstSub will get a changed string on return.

If FirstSub and HandleString are just _using_ the string for something,
but not replacing it with a different string, there is no reason to use
"ref".
I am curious as to why it works, however.

If I have testString and I pass it as a reference to FirstSub, then it has
the reference to testString (not the string itself). When I pass it to
HandleString, aren't I passing a reference to a reference of testString?


No, because C# isn't like C. In C#, when you mention the variable name
then the language dereferences automatically. So, in

void FirstSub(ref string theString)
{
...
}

when you say "theString", you are not talking about the reference to
"theString". You are talking about "theString" itself (which is a
reference to a string). So, no, you never get a reference to a
reference to a reference, because there is no language construct for
talking about "the reference to the reference called 'theString'". The
"ref" simply indicates how "theString" gets passed to the method. Once
inside the FirstSub method, "theString" is just a normal string again.

Apr 18 '06 #8
Mart <ma***********@simpl.co.nz> wrote:
In .NET, String is a Reference Type. It is allocated on the heap, and
the variable that you've declared (testString) contains it's address (a
pointer to it). This means that you will always be passing some form of
reference to the instance rather than the instance itself, whether you
pass the testString variable by ref or by value -- so I'm not sure that
you need to put the 'ref' bit in.


He does if the point is that a method lower down the call chain will
change the value of the parameter to be a different string. For
instance:

using System;

public class Test
{
static void Main()
{
string x = "hello";

Foo (ref x);
Console.WriteLine (x);
}

static void Foo (ref string y)
{
Bar (ref y);
}

static void Bar (ref string z)
{
z = "there";
}
}

The code actually being shown doesn't use this facility, admittedly,
and it looks like the OP does have misconceptions given his reluctance
to pass the string reference by value because "I don't want to pass the
actual string which will get very large".

Obligatory link for this kind of thread:
http://www.pobox.com/~skeet/csharp/parameters.html

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Apr 18 '06 #9
"tshad" <ts**********@ftsolutions.com> ha scritto nel messaggio
news:Ol**************@TK2MSFTNGP02.phx.gbl...
Because I am building the string in another function which can get fairly
large and I don't want to pass the actual string which will get very
large.


IMHO it is not a good design the use of "ref" in a method.
It only add confusion for the use of the method.

For strings also, since they are immutable, there is no reasons to use ref.

Best a simple method following the designing guideline:

public string GetHandledString(string myString)
{
myString = ...
return myString;
}
--

Free .Net Reporting Tool - http://www.neodatatype.net
Apr 18 '06 #10
Fabio wrote:
"tshad" <ts**********@ftsolutions.com> ha scritto nel messaggio
news:Ol**************@TK2MSFTNGP02.phx.gbl...
Because I am building the string in another function which can get fairly
large and I don't want to pass the actual string which will get very
large.

IMHO it is not a good design the use of "ref" in a method.
It only add confusion for the use of the method.


I agree that where possible, pass-by-reference should be avoided - but
sometimes it can make the code simpler.
For strings also, since they are immutable, there is no reasons to use ref.
That's not true. The following two methods have very different effects:

void ChangeMe (ref string x)
{
x = "foo";
}

void DontChangeMe (string x)
{
x = "foo";
}
Best a simple method following the designing guideline:

public string GetHandledString(string myString)
{
myString = ...
return myString;
}


That's fine if you don't need the return value for something else.
Every so often, however, it is useful to use ref/out parameters. Look
at double.TryParse for an example of this. (That uses an out parameter,
but ref parameters can be useful in the same way.)

Jon

Apr 18 '06 #11
"Jon Skeet [C# MVP]" <sk***@pobox.com> ha scritto nel messaggio
Best a simple method following the designing guideline:

public string GetHandledString(string myString)
{
myString = ...
return myString;
}


That's fine if you don't need the return value for something else.
Every so often, however, it is useful to use ref/out parameters. Look
at double.TryParse for an example of this. (That uses an out parameter,
but ref parameters can be useful in the same way.)


You're right, but there are really few occasions that require ref/out.
And I think that also the Fw classes use it so rarely because maybe can make
code run faster, but not more clear.
Elsewhere all the Create<Something>() methods would be Create<Something>(out
Something x).

Don't you think so?

Apr 18 '06 #12
Fabio wrote:
That's fine if you don't need the return value for something else.
Every so often, however, it is useful to use ref/out parameters. Look
at double.TryParse for an example of this. (That uses an out parameter,
but ref parameters can be useful in the same way.)


You're right, but there are really few occasions that require ref/out.
And I think that also the Fw classes use it so rarely because maybe can make
code run faster, but not more clear.
Elsewhere all the Create<Something>() methods would be Create<Something>(out
Something x).

Don't you think so?


It's not that it can make code run faster - it's just that it's only
really useful if you've already used the return value for something
else.

As I said before, it's rarely useful - which is why it's not usually
considered a major omission from Java, for instance - but every so
often it can be pretty handy.

(It's also fairly useful with interop, IIRC. There are lots of Windows
APIs which do this kind of thing, but with pointers. Using ref/out is
the usualy way of handling this.)

Jon

Apr 18 '06 #13

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:11**********************@t31g2000cwb.googlegr oups.com...
Fabio wrote:
As I said before, it's rarely useful - which is why it's not usually
considered a major omission from Java, for instance - but every so
often it can be pretty handy.

(It's also fairly useful with interop, IIRC. There are lots of Windows
APIs which do this kind of thing, but with pointers. Using ref/out is
the usualy way of handling this.)
It's also useful for multiple-value returns:

ParseMyString( string str, out string part1, out string part2, out
string part3) ...

Of course, you can also provide a type for the return, and use the new
object initalizers (when 3.0 comes out...) to set up the return, alieviating
the need for c'tors or a temp:

struct ParseRet { string part1, part2, part3; }
ParseRet ParseMyString( string str)
{
...
return new ParseRet { part1 = ..., part2 = ...,part3 = ...}
}

I can't belive object and collection initializers have taken this long - but
I'll be glad to have them!

If/When c# gets tuple unpacking or generalized structure assignment (LHS
only unification) (a la Python, Ruby, etc.), you could do it this way:

part1, part2, part3 = ParseMyString( str); // 3-ary collection unpacked
and assigned

I thought this was in 3.0, but a glance at the currect spec leads me to
beleive it's not there. (Because "tuples" in c# are really anonymous, but
actual classes.)
But it would be cool if a collection/member destructuring assignment was
supplied, as that can be pretty powerful when needed.

There are probably some tricks with new features such as implicit typing,
anonymous types, etc., in combination w/generics that probably provide other
ways of returning multiple values that have different tradeoffs from the
current methods - but probably the most ideomatic in c# is to just define a
struct.

m

Jon

Apr 18 '06 #14

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Mart <ma***********@simpl.co.nz> wrote:
In .NET, String is a Reference Type. It is allocated on the heap, and
the variable that you've declared (testString) contains it's address (a
pointer to it). This means that you will always be passing some form of
reference to the instance rather than the instance itself, whether you
pass the testString variable by ref or by value -- so I'm not sure that
you need to put the 'ref' bit in.


He does if the point is that a method lower down the call chain will
change the value of the parameter to be a different string. For
instance:

using System;

public class Test
{
static void Main()
{
string x = "hello";

Foo (ref x);
Console.WriteLine (x);
}

static void Foo (ref string y)
{
Bar (ref y);
}

static void Bar (ref string z)
{
z = "there";
}
}

The code actually being shown doesn't use this facility, admittedly,
and it looks like the OP does have misconceptions given his reluctance
to pass the string reference by value because "I don't want to pass the
actual string which will get very large".

Obligatory link for this kind of thread:
http://www.pobox.com/~skeet/csharp/parameters.html


Good article.

But I was a little confused when he was talking about value types. He uses
as his first example:

public struct IntHolder
{
public int i;
}

I would think a struct would be a reference type. I am assuming that this
is a value type because it only contains one value type (int). If it was
something like:

public struct IntHolder
{
public int i; public int j;
}
would it still be a value type?Thanks,Tom> > -- > Jon Skeet -
<sk***@pobox.com>> http://www.pobox.com/~skeet Blog:
http://www.msmvps.com/jon.skeet> If replying to the group, please do not
mail me too
Apr 18 '06 #15
In C#, structs are always value types. Do not confuse C# structs with,
say, C++ structs. They act completely differently.

Apr 18 '06 #16
tshad <ts**********@ftsolutions.com> wrote:
Obligatory link for this kind of thread:
http://www.pobox.com/~skeet/csharp/parameters.html
Good article.

But I was a little confused when he was talking about value types. He uses
as his first example:

public struct IntHolder
{
public int i;
}

I would think a struct would be a reference type.


No - the whole point of declaring something as a struct instead of a
class is to make it a value type instead of a reference type.

I am assuming that this is a value type because it only contains one value type (int). If it was
something like:

public struct IntHolder
{
public int i; public int j;
}
would it still be a value type?


Yes. It's a value type as long as it's declared as a struct instead of
a class.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Apr 18 '06 #17


Jon Skeet [C# MVP] wrote:
Fabio wrote:
That's fine if you don't need the return value for something else.
Every so often, however, it is useful to use ref/out parameters. Look
at double.TryParse for an example of this. (That uses an out parameter,
but ref parameters can be useful in the same way.)


You're right, but there are really few occasions that require ref/out.
And I think that also the Fw classes use it so rarely because maybe can make
code run faster, but not more clear.
Elsewhere all the Create<Something>() methods would be Create<Something>(out
Something x).

Don't you think so?

It's not that it can make code run faster - it's just that it's only
really useful if you've already used the return value for something
else.

As a general rule in programming, I don't think that functions should be able to
create side-effects. Some languages will make sure it doesn't happen, some don't.

eg

classa fn1 ( ref classa a )
{
return operation_on_a;
}

classa thing = fn1 ( ref a ) + a

is dependent on how the compiler handles expressions. Now it could be that we
know C# does it one way, but C++ or D# might do it another way.

iow, if the value of parameters can be changed, they should only occur in void
functions.
Apr 18 '06 #18
Ian Semmel <is***********@NOKUNKrocketcomp.com.au> wrote:
It's not that it can make code run faster - it's just that it's only
really useful if you've already used the return value for something
else.
As a general rule in programming, I don't think that functions should be able to
create side-effects. Some languages will make sure it doesn't happen, some don't.


Even if the variable values don't change, there's often nothing to stop
people manipulating referenced objects - adding to lists, etc.

Side-effects *can* be very useful - they just shouldn't be overused
(just like plenty of other things).
eg

classa fn1 ( ref classa a )
{
return operation_on_a;
}

classa thing = fn1 ( ref a ) + a

is dependent on how the compiler handles expressions. Now it could be that we
know C# does it one way, but C++ or D# might do it another way.
Some languages don't define it; C# does, fortunately.
iow, if the value of parameters can be changed, they should only occur in void
functions.


I'd say the example above is certainly bad style just in terms of
readability, but I don't think it's anything that should be restricted
in the language.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Apr 18 '06 #19

"Ian Semmel" <is***********@NOKUNKrocketcomp.com.au> wrote in message
news:Oz**************@TK2MSFTNGP05.phx.gbl...


Jon Skeet [C# MVP] wrote:
Fabio wrote:
That's fine if you don't need the return value for something else.
Every so often, however, it is useful to use ref/out parameters. Look
at double.TryParse for an example of this. (That uses an out parameter,
but ref parameters can be useful in the same way.)

You're right, but there are really few occasions that require ref/out.
And I think that also the Fw classes use it so rarely because maybe can
make
code run faster, but not more clear.
Elsewhere all the Create<Something>() methods would be
Create<Something>(out
Something x).

Don't you think so?

It's not that it can make code run faster - it's just that it's only
really useful if you've already used the return value for something
else.

As a general rule in programming, I don't think that functions should be
able to create side-effects. Some languages will make sure it doesn't
happen, some don't.

eg

classa fn1 ( ref classa a )
{
return operation_on_a;
}

classa thing = fn1 ( ref a ) + a

is dependent on how the compiler handles expressions. Now it could be that
we know C# does it one way, but C++ or D# might do it another way.

iow, if the value of parameters can be changed, they should only occur in
void functions.


I think a success/failure or status return is quite handy:

if ( DoSomething( a, b, ref out c, ref out d))
// we're golden

This was especially true before nullable values, where it may be hard to
determine from the out params whether the function even suceeded if results
are allowed to be null.
As most functional languages have an implcit notion of success/failure
(where failure sometimes results in backtracking if the language supports
it) even if programming c# in a functional style, I don't think returning
true/false is so bad.

m

Apr 18 '06 #20
Mike <vi********@yahoo.com> wrote:
I think a success/failure or status return is quite handy:

if ( DoSomething( a, b, ref out c, ref out d))
// we're golden

This was especially true before nullable values, where it may be hard to
determine from the out params whether the function even suceeded if results
are allowed to be null.
As most functional languages have an implcit notion of success/failure
(where failure sometimes results in backtracking if the language supports
it) even if programming c# in a functional style, I don't think returning
true/false is so bad.


That's okay *sometimes* - but only sometimes. Unless you think people
are likely to call the method a significant amount in a "failure" case
(as per Double.TryParse etc) I'd favour an exception instead. It's far
more informative than a return value, and is a lot harder to
accidentally ignore.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Apr 18 '06 #21
"Mike" <vi********@yahoo.com> wrote in message
news:ec**************@TK2MSFTNGP03.phx.gbl...
This was especially true before nullable values, where it may be hard to
determine from the out params whether the function even suceeded if
results are allowed to be null.
As most functional languages have an implcit notion of success/failure
(where failure sometimes results in backtracking if the language supports
it) even if programming c# in a functional style, I don't think returning
true/false is so bad.


It is if it's in place of an exception. So often I see code like this:

bool SetSomeValueInSomeList(int index, object value)
{
if(index < 0 || index >= mylist.Count) return false;
mylist[index] = value;
return true;
}

Michael
Apr 18 '06 #22
"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
That's okay *sometimes* - but only sometimes. Unless you think people
are likely to call the method a significant amount in a "failure" case
(as per Double.TryParse etc) I'd favour an exception instead. It's far
more informative than a return value, and is a lot harder to
accidentally ignore.


Plus a lot more consistant. :-)

Michael
Apr 18 '06 #23

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

6 posts views Thread by keepyourstupidspam | last post: by
8 posts views Thread by Dennis Myrén | last post: by
6 posts views Thread by MSDNAndi | last post: by
12 posts views Thread by Andrew Bullock | last post: by
8 posts views Thread by Sanders Kaufman | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.