By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,950 Members | 989 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,950 IT Pros & Developers. It's quick & easy.

'null' references

P: n/a
As explained in "Using pointers vs. references"
http://groups.google.ee/group/borlan...294c7b02e8faca ,
the pointers are allowed to be null, while references must refer an existing
variable of required type. The null is normally used for making optional
parameters. But there is no way to pass null reference in C#. Something is
missing.
Jun 15 '07 #1
Share this Question
Share on Google+
76 Replies


P: n/a
valentin tihomirov <V_*********@best.eewrote:
As explained in "Using pointers vs. references"
http://groups.google.ee/group/borlan...ectpascal/brow
se_thread/thread/683c30f161fc1e9c/ab294c7b02e8faca#ab294c7b02e8faca ,
the pointers are allowed to be null, while references must refer an existing
variable of required type. The null is normally used for making optional
parameters. But there is no way to pass null reference in C#. Something is
missing.
That's using Delphi terminology, which isn't terribly helpful in C#.

In C# null *is* a reference:

<quote>
A reference type value is a reference to an instance of the type, the
latter known as an object. The special value null is compatible with
all reference types and indicates the absence of an instance.
</quote>

and

<quote>
The null literal (§9.4.4.6) evaluates to the null value, which is used
to denote a reference not pointing at any object or array, or the
absence of a value. The null type has a single value, which is the null
value. Hence an expression whose type is the null type can evaluate
only to the null value. There is no way to explicitly write the null
type and, therefore, no way to use it in a declared type.
</quote>

Now, given that, I don't actually see what you're trying to do. You can
pass null as an argument without an problems. Try to describe it in
terms of achieving a goal, rather than being like another 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
Jun 15 '07 #2

P: n/a
As explained in "Using pointers vs. references"
http://groups.google.ee/group/borlan...294c7b02e8faca ,
the pointers are allowed to be null, while references must refer an
existing variable of required type. The null is normally used for making
optional parameters. But there is no way to pass null reference in C#.
Something is missing.
Yes, for those coming from the C++ world such as myself it's an annoyance
(since you can't pass null for "out" or "ref" parameters that you're not
interested in). Other issues include a lack of "const-correctness", no
covariant return types (a must in OOP), the need to initialize all variables
all the time (even though it's not actually required on occasion - you still
have to do it though), and other pet peeves. "C#" certainly has benefits
that C++ can learn from but C++ still has much to teach as well. Part of the
problem with "C#" and .NET in general was its rush to get to market. This
likely resulted from the pressure MSFT was feeling to counter Java before it
was too late. It shows given how generics were introduced only in 2.0 for
instance (they should have been implemented from the outset) and many
classes are now obsolete or deprecated as result (for all intents and
purposes). .NET is therefore forced to carry this excess baggage around
including some ugly class derivations to support both the old interfaces and
their generic counterparts (or consider the even more insidious/pervasive
use of "object" which isn't type-safe and therefore a notorious source of
problems). Most of this will now be around permanently of course which shows
what happens when a language is pushed out the door too soon.
Jun 15 '07 #3

P: n/a
That's using Delphi terminology, which isn't terribly helpful in C#.
Now, given that, I don't actually see what you're trying to do. You can
pass null as an argument without an problems. Try to describe it in
terms of achieving a goal, rather than being like another language.
I do not understand why the terminology, which matches C very well is so
inconsistent with C#. Btw, which language do information technology
scientins base their theories on? Do they fix on some concrete language
explaining their discoveries? I just ask for some typical thing how to do it
in C# refering some other langs as examples.
In C# null *is* a reference:
This is great, but the following code fails to compile:
func(null);
as well as
func(ref null);
Jun 15 '07 #4

P: n/a
"valentin tihomirov" <V_*********@best.eewrote in message
news:e$*************@TK2MSFTNGP02.phx.gbl...
This is great, but the following code fails to compile:
func(null);
as well as
func(ref null);
The first one does compile if the argument to func is a reference type:

void func(object x) {}
....
func(null); //OK

The second one requires a variable:

void func(ref object x) { if (x==null) x=new myclass(); }
....
object y = null;
func (ref y);
//now y contains a reference to a myclass object
Jun 15 '07 #5

P: n/a
object y = null;
func (ref y);
//now y contains a reference to a myclass object
A reference to the special NULL object is not the same thing as the
zero-pointer, which refers nothing (zero address is invalid). That is why I
point out that pointer argument itself is allowed to be zero while reference
is not. A reference must always refer something (whether a valid object or
'null' object).

Thanks for the hint. I suppose it is the supposed way to do it in C#. It has
two disadvantages though: 1) you must declare a bogus reference variable;
and 2) initialize it before passing to the function, where you could just
pass a 0 right away. Furthermore, it prevents you from using 'out'
arguments.

Actually, pointers are needed to write directly to the address they points
to. Using reference to the bogus null-object, which we leave unmodifed when
assign a new value to the reference to return. This makes passing the bogus
value by reference a bit nonsenes. Pointers reach the same effect without
creating any bogus objects, which as stated above has additional usage
advantages.

Peahaps, too much words for the issue. Yet, I do not know any places where
it is discussed.
Jun 15 '07 #6

P: n/a
On Fri, 15 Jun 2007 11:09:40 -0700, valentin tihomirov
<V_*********@best.eewrote:
A reference to the special NULL object is not the same thing as the
zero-pointer, which refers nothing (zero address is invalid).
Frankly, I don't see how it's all that different at all. There are some
minor semantic differences, but for all intents and purposes a "null" in
C# is pretty much the same as a "null" in C++.
That is why I
point out that pointer argument itself is allowed to be zero while
reference
is not. A reference must always refer something (whether a valid object
or
'null' object).
You can't use a null for a reference parameter in C++ either. The
following generates a compile error, just as the "ref" parameter example
you gave for C# does:

void Func(int &i)
{
}

void Caller()
{
Func(nullptr);
}
Thanks for the hint. I suppose it is the supposed way to do it in C#. It
has
two disadvantages though: 1) you must declare a bogus reference variable;
and 2) initialize it before passing to the function, where you could just
pass a 0 right away. Furthermore, it prevents you from using 'out'
arguments.
Again, how is this difference from passing by reference in C++?
Actually, pointers are needed to write directly to the address they
points
to.
In C#, a reference is needed to write directly to the address it points
to. Same thing.
Using reference to the bogus null-object, which we leave unmodifed when
assign a new value to the reference to return.
I don't understand this statement. How can you leave something unmodified
while at the same time assigning a new value?
This makes passing the bogus
value by reference a bit nonsenes. Pointers reach the same effect without
creating any bogus objects, which as stated above has additional usage
advantages.
The only real difference I see is that if you pass a pointer to a
_pointer_ in C++, that allows you to have similar behavior to (but not
exactly the same as) passing by reference, while at the same time allowing
for the parameter to be optional. For example:

void Func(int *pi)
{
if (pi != null)
{
*pi = <some result goes here>;
}
}

void Caller()
{
int i;

Func(&i);
Func(null);
}

However, I fail to see how this is really much of an advantage. In C# you
would be required to create a dummy local that you would just ignore. In
C++ you have to have code in the function itself to check whether the
parameter is null. Either way, there's extra code, and in the C# case it
eliminates the chance of a null-dereference run-time error (in C++, if you
forget to check for the parameter being null, you can crash).

I see this as _better_, not worse.
Peahaps, too much words for the issue. Yet, I do not know any places
where
it is discussed.
Frankly, after having seen several of these "rants" from you, I am left
wondering why you bother to use C#. I don't really think you understand
the issues you're talking about anyway, but even assuming you do, it seems
to me that if you feel C++ is so much better suited to your needs, then
that's the language you ought to be using.

Pete
Jun 15 '07 #7

P: n/a
PS

"valentin tihomirov" <V_*********@best.eewrote in message
news:Ob**************@TK2MSFTNGP04.phx.gbl...
>
> object y = null;
func (ref y);
//now y contains a reference to a myclass object

A reference to the special NULL object is not the same thing as the
zero-pointer, which refers nothing (zero address is invalid). That is why
I point out that pointer argument itself is allowed to be zero while
reference is not. A reference must always refer something (whether a valid
object or 'null' object).

Thanks for the hint. I suppose it is the supposed way to do it in C#. It
has two disadvantages though: 1) you must declare a bogus reference
variable; and 2) initialize it before passing to the function, where you
could just pass a 0 right away. Furthermore, it prevents you from using
'out' arguments.

Actually, pointers are needed to write directly to the address they points
to. Using reference to the bogus null-object, which we leave unmodifed
when assign a new value to the reference to return. This makes passing the
bogus value by reference a bit nonsenes. Pointers reach the same effect
without creating any bogus objects, which as stated above has additional
usage advantages.

Peahaps, too much words for the issue. Yet, I do not know any places where
it is discussed.
Personally I find these types of discussions to have null value.

PS
Jun 15 '07 #8

P: n/a
Frankly, I don't see how it's all that different at all. There are some
minor semantic differences, but for all intents and purposes a "null" in
C# is pretty much the same as a "null" in C++.
Despite you cannot pass the null as argument, which is ubequitous, the most
frequent parameter in C.
Again, how is this difference from passing by reference in C++?
Where do I tell that C# references are different from C++ references? I was
speaking about the difference between "pointers" and "references"!

Using reference to the bogus null-object, which we leave unmodifed when
assign a new value to the reference to return.
I don't understand this statement. How can you leave something unmodified
while at the same time assigning a new value?

Very easily.
function (ref a) {
if (a != null)
a = new object();
}

b = null;
function(ref b);

The null passed by reference is left unmodified ;-) The same effect would be
reached by different 'nulls'
NULL = new Object();
func(ref r) {
if (r != NULL)
r = returnVal;
}

However, I fail to see how this is really much of an advantage. In C# you
would be required to create a dummy local that you would just ignore. In
C++ you have to have code in the function itself to check whether the
parameter is null. Either way, there's extra code, and in the C# case it
eliminates the chance of a null-dereference run-time error (in C++, if you
forget to check for the parameter being null, you can crash).
... and the water is wet. But I did not address this issue! Read it once
again:
[quote] It has
two disadvantages though: 1) you must declare a bogus reference
variable;
and 2) initialize it before passing to the function, where you could
just
pass a 0 right away. Furthermore, it prevents you from using 'out'
arguments.[end quote]

Who argues that we should assign null (optional) arguments if the null
passed means "user does not want us to out anything"?

I don't really think you understand the issues you're talking about
anyway
Because you read and respond on the thing I do not address.
Jun 15 '07 #9

P: n/a
valentin tihomirov <V_*********@best.eewrote:
object y = null;
func (ref y);
//now y contains a reference to a myclass object

A reference to the special NULL object is not the same thing as the
zero-pointer, which refers nothing (zero address is invalid). That is why I
point out that pointer argument itself is allowed to be zero while reference
is not. A reference must always refer something (whether a valid object or
'null' object).
Only according to your terminology. In C#, a reference can refer to a
real object or it can be null. There is no such thing as a "null
object".
Thanks for the hint. I suppose it is the supposed way to do it in C#. It has
two disadvantages though: 1) you must declare a bogus reference variable;
and 2) initialize it before passing to the function, where you could just
pass a 0 right away. Furthermore, it prevents you from using 'out'
arguments.
Yes, both "out" and "ref" require you to use an actual variable. This
is entirely reasonable given the purpose of ref, IMO.
Actually, pointers are needed to write directly to the address they points
to. Using reference to the bogus null-object, which we leave unmodifed when
assign a new value to the reference to return. This makes passing the bogus
value by reference a bit nonsenes. Pointers reach the same effect without
creating any bogus objects, which as stated above has additional usage
advantages.
No objects are created in the code at the top of this post.

--
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
Jun 15 '07 #10

P: n/a
valentin tihomirov <V_*********@best.eewrote:
Frankly, I don't see how it's all that different at all. There are some
minor semantic differences, but for all intents and purposes a "null" in
C# is pretty much the same as a "null" in C++.

Despite you cannot pass the null as argument, which is ubequitous, the most
frequent parameter in C.
It's already been pointed out that you *can* use null as an argument.
Again, how is this difference from passing by reference in C++?

Where do I tell that C# references are different from C++ references? I was
speaking about the difference between "pointers" and "references"!
You need to understand the difference between *a* reference (which is
like a C++ pointer) and passing something *by* reference which is like
passing by reference in C++.

<snip>

--
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
Jun 15 '07 #11

P: n/a
On Fri, 15 Jun 2007 23:02:41 +0300, "valentin tihomirov"
<V_*********@best.eewrote:
>Frankly, I don't see how it's all that different at all. There are some
minor semantic differences, but for all intents and purposes a "null" in
C# is pretty much the same as a "null" in C++.

Despite you cannot pass the null as argument, which is ubequitous, the most
frequent parameter in C.
Quit trying to program in C with C# syntax. Rarely is there a need to
pass a reference type by-ref in C#. In fact, in the past 5 years of
working with C#/.NET, I can't recall ever doing a ref-by-ref method.
The only times I've even used a by-ref was with a struct, either in an
area where I needed maximum performance (and testing revealed a
bottleneck), or for P/Invoke.

Almost always, whenever I see a reference type passed by-ref, I think
WTF are they doing here, and the code is usually wrong.

Please, show me where a ref-by-ref is needed in C#/.NET

Austin

<snip>
Jun 15 '07 #12

P: n/a

"valentin tihomirov" <V_*********@best.eewrote in message
news:Ob**************@TK2MSFTNGP04.phx.gbl...
>
> object y = null;
func (ref y);
//now y contains a reference to a myclass object

A reference to the special NULL object is not the same thing as the
zero-pointer, which refers nothing (zero address is invalid). That is why
I
There is no special NULL object, and a null pointer has the integral value
zero (try new IntPtr(null).ToInt32()).
point out that pointer argument itself is allowed to be zero while
reference is not. A reference must always refer something (whether a valid
object or 'null' object).

Thanks for the hint. I suppose it is the supposed way to do it in C#. It
has two disadvantages though: 1) you must declare a bogus reference
variable; and 2) initialize it before passing to the function, where you
could just pass a 0 right away. Furthermore, it prevents you from using
'out' arguments.

Actually, pointers are needed to write directly to the address they points
to. Using reference to the bogus null-object, which we leave unmodifed
when assign a new value to the reference to return. This makes passing the
bogus value by reference a bit nonsenes. Pointers reach the same effect
without creating any bogus objects, which as stated above has additional
usage advantages.

Peahaps, too much words for the issue. Yet, I do not know any places where
it is discussed.
Jun 15 '07 #13

P: n/a
>You can't use a null for a reference parameter in C++ either. The
following generates a compile error, just as the "ref" parameter example
you gave for C# does:
Yes you can. You do have to pass the correct type, however.

void Func(int &i)
{
}

void Caller()
{
Func(*(int*)nullptr);
}

It's a very bad idea, true, but people who use references instead of
pointers simply because "I would have to check for NULL pointers, and
references can't be NULL" are simply misinformed.

Jun 15 '07 #14

P: n/a

"Austin Ehlers" <austin.ehlers.spam.@gmail.comwrote in message
news:ho********************************@4ax.com...
On Fri, 15 Jun 2007 23:02:41 +0300, "valentin tihomirov"
<V_*********@best.eewrote:
>>Frankly, I don't see how it's all that different at all. There are some
minor semantic differences, but for all intents and purposes a "null" in
C# is pretty much the same as a "null" in C++.

Despite you cannot pass the null as argument, which is ubequitous, the
most
frequent parameter in C.

Quit trying to program in C with C# syntax. Rarely is there a need to
pass a reference type by-ref in C#. In fact, in the past 5 years of
working with C#/.NET, I can't recall ever doing a ref-by-ref method.
The only times I've even used a by-ref was with a struct, either in an
area where I needed maximum performance (and testing revealed a
bottleneck), or for P/Invoke.

Almost always, whenever I see a reference type passed by-ref, I think
WTF are they doing here, and the code is usually wrong.

Please, show me where a ref-by-ref is needed in C#/.NET
Immutable reference types, like string. Copy-on-write. Various times you
need ReferenceEquals, not simply a clone, but the return value is already
used.
>
Austin

<snip>
Jun 15 '07 #15

P: n/a
Ben Voigt [C++ MVP] <rb*@nospam.nospamwrote:
Please, show me where a ref-by-ref is needed in C#/.NET

Immutable reference types, like string. Copy-on-write. Various times you
need ReferenceEquals, not simply a clone, but the return value is already
used.
While I can think of some reasons why pass-by-ref of reference types is
sometimes useful, I can't make head or tail of your reply,
unfortunately. However, I suspect I could learn something if you'd be
willing to elaborate.

--
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
Jun 15 '07 #16

P: n/a
Haven't read the whole thread but in C++... a pointer is used when the
object may/can not exist; otherwise a reference is used when the object must
exist.

You can force a NULL reference to be used in C++ but it's definately not a
practice that I'd recommend.

If you are using a pointer then the check for NULL is imperative where as a
reference must be bound to an object.

- Andy

"Ben Voigt [C++ MVP]" <rb*@nospam.nospamwrote in message
news:97**********************************@microsof t.com...
>
>>You can't use a null for a reference parameter in C++ either. The
following generates a compile error, just as the "ref" parameter example
you gave for C# does:

Yes you can. You do have to pass the correct type, however.

void Func(int &i)
{
}

void Caller()
{
Func(*(int*)nullptr);
}

It's a very bad idea, true, but people who use references instead of
pointers simply because "I would have to check for NULL pointers, and
references can't be NULL" are simply misinformed.

Jun 15 '07 #17

P: n/a

"Jon Skeet [C# MVP]" <sk***@pobox.comwrote in message
news:MP*********************@msnews.microsoft.com. ..
Ben Voigt [C++ MVP] <rb*@nospam.nospamwrote:
Please, show me where a ref-by-ref is needed in C#/.NET

Immutable reference types, like string. Copy-on-write. Various times
you
need ReferenceEquals, not simply a clone, but the return value is already
used.

While I can think of some reasons why pass-by-ref of reference types is
sometimes useful, I can't make head or tail of your reply,
unfortunately. However, I suspect I could learn something if you'd be
willing to elaborate.
The argument against pass ref class by-ref seems to be that you should
modify the referenced class in place. That isn't possible for immutable
types, like string. To return string data by reference, you can pass a
string variable by-ref, (or use a StringBuilder).

Copy-on-write: If you aren't allowed to modify the object in-place, but have
to clone it in order to change it, then the caller's reference needs to be
updated to the new copy. Again, ref-by-ref. strings are actually a subset
of this case.

If the resulting value has to compare equal by referential equality every
time it is returned, then you need to set the caller's reference equal to
your own. Again, ref-by-ref.
>
--
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
Jun 15 '07 #18

P: n/a

"Andy Bates" <an**@ussdev.comwrote in message
news:e8**************@TK2MSFTNGP05.phx.gbl...
Haven't read the whole thread but in C++... a pointer is used when the
object may/can not exist; otherwise a reference is used when the object
must exist.
Again, a reference can be just as invalid as a pointer.
>
You can force a NULL reference to be used in C++ but it's definately not a
practice that I'd recommend.

If you are using a pointer then the check for NULL is imperative where as
a reference must be bound to an object.
No, it isn't. You can make the contract such that "such and such argument
must not be NULL", then you don't need to check it. And no, a reference
doesn't need to be bound to an object. *p creates a reference for any
pointer p. If the pointer was NULL, there is no object.

Admittedly my example was contrived, that was to use as much of the previous
poster's incorrect claim as possible.
>
- Andy

"Ben Voigt [C++ MVP]" <rb*@nospam.nospamwrote in message
news:97**********************************@microsof t.com...
>>
>>>You can't use a null for a reference parameter in C++ either. The
following generates a compile error, just as the "ref" parameter example
you gave for C# does:

Yes you can. You do have to pass the correct type, however.

void Func(int &i)
{
}

void Caller()
{
Func(*(int*)nullptr);
}

It's a very bad idea, true, but people who use references instead of
pointers simply because "I would have to check for NULL pointers, and
references can't be NULL" are simply misinformed.

Jun 15 '07 #19

P: n/a
On Fri, 15 Jun 2007 14:04:26 -0700, Ben Voigt [C++ MVP]
<rb*@nospam.nospamwrote:
It's a very bad idea, true, but people who use references instead of
pointers simply because "I would have to check for NULL pointers, and
references can't be NULL" are simply misinformed.
It's true. In C++ you can use casting to get around practically any
limitation intentionally put into the language.

I don't see how that invalidates my point though. I have never written
C++ code that checks something passed by reference for null references,
nor have I ever had to maintain code written that way.

I never suggested that the reason to use references was to avoid having to
check for null pointers, but I do feel that is in fact an advantage (if
the caller wants to explicitly get around that safe-guard, that's a bug in
the caller akin to using Reflection in C# to get around a variety of
safe-guards C# puts into place), and I bristle at your implication (if not
outright accusation) that I am "misinformed" just for thinking so.

Pete
Jun 15 '07 #20

P: n/a
On Fri, 15 Jun 2007 13:02:41 -0700, valentin tihomirov
<V_*********@best.eewrote:
Despite you cannot pass the null as argument, which is ubequitous, the
most
frequent parameter in C.
You _can_ pass null as an argument. You just can't pass null as an
argument for a "ref" parameter.

>Again, how is this difference from passing by reference in C++?

Where do I tell that C# references are different from C++ references? I
was
speaking about the difference between "pointers" and "references"!
Since a "ref" parameter is essentially the same as C++'s "&" by-reference
parameter, and since the "ref" parameter type (along with "out" which isa
special case of "ref") is the only situation in which your complaint about
not being able to pass null is true, _that_ is "where you tell that C#
references are different from C++ references".

You brought it up. I'm just pointing out the fallacy in your complaint.
>>Using reference to the bogus null-object, which we leave unmodifed when
assign a new value to the reference to return.
>I don't understand this statement. How can you leave something
unmodified
while at the same time assigning a new value?

Very easily.
function (ref a) {
if (a != null)
a = new object();
}

b = null;
function(ref b);
The above code does _not_ leave "b" unmodified when an new value is
assigned. It does leave "b" unmodified in the example calling code, but
that's only because the function also does not assign a new value.
The null passed by reference is left unmodified ;-)
The null passed by reference would be left unmodified in any case. It's
only "b" that would be modified or not, as that's the variable passed by
reference.
The same effect would be
reached by different 'nulls'
NULL = new Object();
func(ref r) {
if (r != NULL)
r = returnVal;
}
I have no idea what you expect that code to do. You can't assign an
object reference ("new Object()") to "null". You haven't declared "NULL",
so I don't know if you mean that to be the same as "null", or something
entirely different.
>However, I fail to see how this is really much of an advantage. In C#
you
would be required to create a dummy local that you would just ignore.In
C++ you have to have code in the function itself to check whether the
parameter is null. Either way, there's extra code, and in the C# case
it
eliminates the chance of a null-dereference run-time error (in C++, if
you
forget to check for the parameter being null, you can crash).

.. and the water is wet. But I did not address this issue!
Which issue? I agree that you didn't specifically raise the question of
checking for null values. However, that _is_ really the only practical
difference between your apparent desire to pass something by a pointer to
the variable versus the C# "ref" parameter type.

In that respect, you certainly did by implication "address this issue".
[quote]
Read it once
again:
It has
two disadvantages though: 1) you must declare a bogus reference
variable;
So too you must in C++, if using "by-reference" parameter passing.
and 2) initialize it before passing to the function, where you could
just
pass a 0 right away. Furthermore, it prevents you from using 'out'
arguments.[end quote]
What prevents you from using "out" arguments? The use of the "out"
parameter type is in fact how you can avoid having to initialize the
variable passed into the function.
Who argues that we should assign null (optional) arguments if the null
passed means "user does not want us to out anything"?
What do you mean by "assign null arguments"? You can't assign anything to
a null reference or pointer.
>I don't really think you understand the issues you're talking about
anyway

Because you read and respond on the thing I do not address.
The fact that you think my response isn't relevant to the thing you are
talking about is in fact the very evidence that you don't understand the
thing that you are talking about.

Pete
Jun 15 '07 #21

P: n/a
The fact that you think my response isn't relevant to the thing you are
talking about is in fact the very evidence that you don't understand the
thing that you are talking about.
I haven't read the entire thread but the issue to me boils down to this. Why
isn't the following allowed:

void Func(out Whatever whatever)
{
if (whatever != null)
{
whatever = new Whatever();
}
}

Func(null);
Jun 15 '07 #22

P: n/a
>>You can't use a null for a reference parameter in C++ either. The
>>following generates a compile error, just as the "ref" parameter example
you gave for C# does:

Yes you can. You do have to pass the correct type, however.

void Func(int &i)
{
}

void Caller()
{
Func(*(int*)nullptr);
}

It's a very bad idea, true, but people who use references instead of
pointers simply because "I would have to check for NULL pointers, and
references can't be NULL" are simply misinformed.
Not only is it bad, it's undefined behaviour so it doesn't qualify as valid
C++. You can't legally dereference a null pointer nor is a null reference
legally possible.
Jun 15 '07 #23

P: n/a
On Fri, 15 Jun 2007 16:27:50 -0500, "Ben Voigt [C++ MVP]"
<rb*@nospam.nospamwrote:
>
"Jon Skeet [C# MVP]" <sk***@pobox.comwrote in message
news:MP*********************@msnews.microsoft.com ...
>Ben Voigt [C++ MVP] <rb*@nospam.nospamwrote:
>Please, show me where a ref-by-ref is needed in C#/.NET

Immutable reference types, like string. Copy-on-write. Various times
you
need ReferenceEquals, not simply a clone, but the return value is already
used.

While I can think of some reasons why pass-by-ref of reference types is
sometimes useful, I can't make head or tail of your reply,
unfortunately. However, I suspect I could learn something if you'd be
willing to elaborate.

The argument against pass ref class by-ref seems to be that you should
modify the referenced class in place. That isn't possible for immutable
types, like string. To return string data by reference, you can pass a
string variable by-ref, (or use a StringBuilder).
Why not just use the return value, like String does? If you have
multiple parameters that need to be changed, then it is usually bad
code, trying to do too much in one method, and should be refactored
into a better design.

Seeing a reference type passed by-ref in code, particularly from
someone new to C#/.NET, is like seeing a class with a finalizer: it's
occasionally right, but not often.

(I'm also ignoring things like Remoting, as that's outside normal
C#/.NET usage.)
>Copy-on-write: If you aren't allowed to modify the object in-place, but have
to clone it in order to change it, then the caller's reference needs to be
updated to the new copy. Again, ref-by-ref. strings are actually a subset
of this case.
Same.
>If the resulting value has to compare equal by referential equality every
time it is returned, then you need to set the caller's reference equal to
your own. Again, ref-by-ref.
Sorry, I'm not following you here. Any example code?

Austin
Jun 15 '07 #24

P: n/a
On Fri, 15 Jun 2007 15:17:36 -0700, Austin Ehlers
<austin.ehlers.spam.@gmail.comwrote:
Why not just use the return value, like String does? If you have
multiple parameters that need to be changed, then it is usually bad
code, trying to do too much in one method, and should be refactored
into a better design.
I agree that for immutable types, the best solution is usually to return a
new instance as the result from a method, rather than using a "ref"
parameter. However, consider situations like TryParse where you want to
return more than one value: the new instance and a result code of some
sort, for example. Are you suggesting that the TryParse pattern is
indicative of poor design?

It's true that these situations aren't very common. But I wouldn't go so
far as to say that one never needs to pass reference variables by
reference.
Seeing a reference type passed by-ref in code, particularly from
someone new to C#/.NET, is like seeing a class with a finalizer: it's
occasionally right, but not often.
"Occasionally right" being the operative phrase, IMHO. You wrote "Please,
show me where a ref-by-ref is needed in C#/.NET". I interpreted Ben's
reply simply as doing just that, showing you where it's needed.

Pete
Jun 15 '07 #25

P: n/a
On Fri, 15 Jun 2007 15:10:57 -0700, Larry Smith <no_spam@_nospam.com
wrote:
I haven't read the entire thread but the issue to me boils down to
this. Why
isn't the following allowed:

void Func(out Whatever whatever)
{
if (whatever != null)
{
whatever = new Whatever();
}
}

Func(null);
I think it does boil down to that, and I think the answer is the same as
the reason why you can't do this in C++:

void Func(Whatever &whatever)
{
if (whatever != null)
{
whatever = new Whatever();
}
}

Func(nullptr);

In other words, there's no practical different in this respect between
C++ and C#, in spite of what the OP claims.
Jun 15 '07 #26

P: n/a
In other words, there's no practical different in this respect between
C++ and C#, in spite of what the OP claims.
Apparently so but it didn't have to be that way. It may be a religious issue
but I would have voted to support it.
Jun 15 '07 #27

P: n/a
On Fri, 15 Jun 2007 15:39:24 -0700, "Peter Duniho"
<Np*********@nnowslpianmk.comwrote:
>On Fri, 15 Jun 2007 15:17:36 -0700, Austin Ehlers
<austin.ehlers.spam.@gmail.comwrote:
>Why not just use the return value, like String does? If you have
multiple parameters that need to be changed, then it is usually bad
code, trying to do too much in one method, and should be refactored
into a better design.

I agree that for immutable types, the best solution is usually to return a
new instance as the result from a method, rather than using a "ref"
parameter. However, consider situations like TryParse where you want to
return more than one value: the new instance and a result code of some
sort, for example. Are you suggesting that the TryParse pattern is
indicative of poor design?

It's true that these situations aren't very common. But I wouldn't go so
far as to say that one never needs to pass reference variables by
reference.
But is that a reference type? Besides IPAddress.TryParse, they're all
structs. (Notice I said "usually bad, trying to do too much in one
method". Parsing a string into a type is a common, single idea).
>Seeing a reference type passed by-ref in code, particularly from
someone new to C#/.NET, is like seeing a class with a finalizer: it's
occasionally right, but not often.

"Occasionally right" being the operative phrase, IMHO. You wrote "Please,
show me where a ref-by-ref is needed in C#/.NET". I interpreted Ben's
reply simply as doing just that, showing you where it's needed.
And that's fine. I'm just trying to show the OP that things are
different in C# than C/C++, and trying to use C-style code will lead
to a bad design.

Austin
Jun 16 '07 #28

P: n/a
Ben Voigt [C++ MVP] <rb*@nospam.nospamwrote:
While I can think of some reasons why pass-by-ref of reference types is
sometimes useful, I can't make head or tail of your reply,
unfortunately. However, I suspect I could learn something if you'd be
willing to elaborate.

The argument against pass ref class by-ref seems to be that you should
modify the referenced class in place. That isn't possible for immutable
types, like string. To return string data by reference, you can pass a
string variable by-ref, (or use a StringBuilder).
Agreed.
Copy-on-write: If you aren't allowed to modify the object in-place, but have
to clone it in order to change it, then the caller's reference needs to be
updated to the new copy. Again, ref-by-ref. strings are actually a subset
of this case.
Right, I 'm with you.
If the resulting value has to compare equal by referential equality every
time it is returned, then you need to set the caller's reference equal to
your own. Again, ref-by-ref.
Hmm... that may be an idiom I've never come across. The first two make
absolute sense (even if they're fairly rarely required), but this one
is outside my experience.

--
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
Jun 16 '07 #29

P: n/a
Peter Duniho <Np*********@nnowslpianmk.comwrote:
Despite you cannot pass the null as argument, which is ubequitous, the
most frequent parameter in C.

You _can_ pass null as an argument. You just can't pass null as an
argument for a "ref" parameter.
And it's important to note that it's not to do with it being null -
it's to do with being a *value* rather than a *variable*. If you try to
use the result of a method call as a ref parameter you fail in the same
way - ditto if you use a string literal.

<snip>

--
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
Jun 16 '07 #30

P: n/a
Larry Smith <no_spam@_nospam.comwrote:
The fact that you think my response isn't relevant to the thing you are
talking about is in fact the very evidence that you don't understand the
thing that you are talking about.

I haven't read the entire thread but the issue to me boils down to this. Why
isn't the following allowed:

void Func(out Whatever whatever)
{
if (whatever != null)
{
whatever = new Whatever();
}
}

Func(null);
For two reasons:

1) out/ref arguments must be *variables* not values
2) The value of an out parameter isn't definitely assigned at the start
of a method, so you can't compare it with null.

--
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
Jun 16 '07 #31

P: n/a
It's already been pointed out that you *can* use null as an argument.
Neither func(null), nor func(ref null) works. I have checked myself.

Again, how is this difference from passing by reference in C++?

Where do I tell that C# references are different from C++ references? I
was
speaking about the difference between "pointers" and "references"!

You need to understand the difference between *a* reference (which is
like a C++ pointer) and passing something *by* reference which is like
passing by reference in C++.
C++ references are also "like" C++ pointers. But not the same. They are
different. Nulls are not allowed where reference is required. That is the
difference.
Jun 16 '07 #32

P: n/a
Since a "ref" parameter is essentially the same as C++'s "&" by-reference

THEY ARE NOT !!!

Look at the google newsgruop I reference
parameter, and since the "ref" parameter type (along with "out" which is a
special case of "ref") is the only situation in which your complaint about
not being able to pass null is true, _that_ is "where you tell that C#
references are different from C++ references".
Show me where I tell that Delphi/C++ references are different from C#
references? I repeat once again, THESE ARE POINTERS WHICH ARE DIFFERENT FROM
REFERENCES !!!

The same effect would be
reached by different 'nulls'
NULL = new Object();
func(ref r) {
if (r != NULL)
r = returnVal;
}
I have no idea what you expect that code to do. You can't assign an
object reference ("new Object()") to "null". You haven't declared "NULL",
so I don't know if you mean that to be the same as "null", or something
entirely different.
NULL is a marker. I could name it INVALID_HANDLE or somethig. The usage is
the same as you do with 'null' marker. You use the marker to inform the
function that you do not want to obtain a result via the 'ref' param. That
is the different with pointer argument. With the pointer you have an option:
whether to pass a reference or not to pass. With the ref argument you have
no option -- the reference must be passed. You addign it a bogus marker. But
the function is still capable to return a value via the reference. The
program will not crush. It will if null pointer is used.

Importing a dll function, one may declare their arguments wheter as poitners
of references. Both will work, because internal mechanics, the
implementation is the same. But reference prevents passing 'null'. The
compiler will not allow. They must refer existing object.

Is it so hard to understand? Why Delphi noobs understad this difference
between declarations from the start? Should be my bad explanation.

Which issue? I agree that you didn't specifically raise the question of
checking for null values. However, that _is_ really the only practical
difference between your apparent desire to pass something by a pointer to
the variable versus the C# "ref" parameter type.
In that respect, you certainly did by implication "address this issue".
I did not ask anybody to warn me about the dangers of using null pointers.

> and 2) initialize it before passing to the function, where you could
just
pass a 0 right away. Furthermore, it prevents you from using 'out'
arguments.[end quote]
What prevents you from using "out" arguments? The use of the "out"
parameter type is in fact how you can avoid having to initialize the
variable passed into the function.
You suggest that I pass a bogus ref var initialized to 'null' and you do not
understand that this prevents me from specifying the function param as
'out'? Have you tried to read the 'out' parameters in the funtion?
>Who argues that we should assign null (optional) arguments if the null
passed means "user does not want us to out anything"?
What do you mean by "assign null arguments"? You can't assign anything to
a null reference or pointer.
I mean that if user sepcifies 'null' in the pointer argument, (s)he does not
refer anything. This means, (s)he does not pass any data in neither wants
any data out. And I do not argue that we should read/write address 0
crashing the app.

>>I don't really think you understand the issues you're talking about
anyway
Because you read and respond on the thing I do not address.
The fact that you think my response isn't relevant to the thing you are
talking about is in fact the very evidence that you don't understand the
thing that you are talking about.
Evidence? Can you show me the prove? So far, I will go on thinking that your
answers are not relevant because thet are not relevant.
Jun 16 '07 #33

P: n/a
Larry grasped it very well. But the correct answer, which I assumed in the
OP, is not because C# references are the same as references in other
languages. Doing so is not allowed because the pointers, which are allowed
to refer any areas of memory where no valid objects exist including address
0, are not supported in C#.
Jun 16 '07 #34

P: n/a
>You _can_ pass null as an argument. You just can't pass null as an
>argument for a "ref" parameter.

And it's important to note that it's not to do with it being null -
it's to do with being a *value* rather than a *variable*. If you try to
use the result of a method call as a ref parameter you fail in the same
way - ditto if you use a string literal.
To be relevant to the raised issue, it is important to note that the topic
is about passing arguemtns by pointers/references and that the 'null' is a
'literal'. That is why I state that 'null' is not allowed to pass as
argument.
Jun 16 '07 #35

P: n/a
>Thanks for the hint. I suppose it is the supposed way to do it in C#. It
has
two disadvantages though: 1) you must declare a bogus reference variable;
and 2) initialize it before passing to the function, where you could just
pass a 0 right away. Furthermore, it prevents you from using 'out'
arguments.

Yes, both "out" and "ref" require you to use an actual variable. This
is entirely reasonable given the purpose of ref, IMO.
But you cannot read the 'out' parameter in order to accoumplish the trick of
passing 'null' reference.
Jun 16 '07 #36

P: n/a
John Brown wrote:
>As explained in "Using pointers vs. references"
http://groups.google.ee/group/borlan...294c7b02e8faca ,
the pointers are allowed to be null, while references must refer an
existing variable of required type. The null is normally used for making
optional parameters. But there is no way to pass null reference in C#.
Something is missing.

Yes, for those coming from the C++ world such as myself it's an annoyance
(since you can't pass null for "out" or "ref" parameters that you're not
interested in).
I don't really see that as a problem. If a method has ref/out parameter
that you are not interrested in, the method is not intended for what you
are interrested in either. If you are using a method for something other
than it was intended for, you still have to supply the parameters for
what it was intended for.

Besides, ref/out parameters are rarely used in oop anyway. :)
Other issues include a lack of "const-correctness", no
covariant return types (a must in OOP),
Hardly a must, but it would be nice.
the need to initialize all variables
all the time (even though it's not actually required on occasion - you still
have to do it though),
I think that is a good thing. It makes you write code that corresponds
to the business rules, instead of writing code that relies on the
business rules never changing. If the rules change (and some surely
will), the compiler can catch any code that you failed to change,
instead of merrily create code that uses undefined values.

If you really think that it's a problem, you can use VB instead, which
does initialise the variables automatically. This of course introduces
some other potential problems, though.
and other pet peeves. "C#" certainly has benefits
that C++ can learn from but C++ still has much to teach as well. Part of the
problem with "C#" and .NET in general was its rush to get to market. This
likely resulted from the pressure MSFT was feeling to counter Java before it
was too late. It shows given how generics were introduced only in 2.0 for
instance (they should have been implemented from the outset) and many
classes are now obsolete or deprecated as result (for all intents and
purposes). .NET is therefore forced to carry this excess baggage around
including some ugly class derivations to support both the old interfaces and
their generic counterparts (or consider the even more insidious/pervasive
use of "object" which isn't type-safe and therefore a notorious source of
problems). Most of this will now be around permanently of course which shows
what happens when a language is pushed out the door too soon.
I surely agree that the early release does cause some baggage in the
framework. If it was a correct decision or not businesswise, that's hard
to tell, but I am sure that they were aware of the consequences when
they made the decision. A business makes business decisons.

--
Göran Andersson
_____
http://www.guffa.com
Jun 16 '07 #37

P: n/a
Larry Smith <no_spam@_nospam.comwrote:
The fact that you think my response isn't relevant to the thing you are
talking about is in fact the very evidence that you don't understand
the
thing that you are talking about.

I haven't read the entire thread but the issue to me boils down to this.
Why
isn't the following allowed:

void Func(out Whatever whatever)
{
if (whatever != null)
{
whatever = new Whatever();
}
}

Func(null);

For two reasons:

1) out/ref arguments must be *variables* not values
2) The value of an out parameter isn't definitely assigned at the start
of a method, so you can't compare it with null.
You're explaining the language's existing rules which is fine, but I'm
questioning why it was done that way in the first place. Let's say I have a
function like "_splitpath" in the CRT. It takes a full path name as arg1 and
returns its drive letter, directory, file name and extension in the next
four "out" parameters. I'm only interested in the directory for instance so
I want to pass "null" for the other "out" arguments. I can't do this however
which is very inconvenient. I'm forced to pass all "out" arguments IOW.
Someone might argue not to design methods like this but there's nothing
inherently wrong with it so it's ultimately the programmer's choice. It may
also prove more efficient in some cases, letting the function know it
doesn't have to carry out the extra work of retrieving all "out" parameters.
Nor do I have to create additional methods to retrieve each individual piece
of info or otherwise create an extra class to store all this data. Sometimes
I'm even just intersested in a function's return value without caring about
the "out" parameter(s). Barring any tangible constraints on the language's
ability to implement this feature, I see no valid reason why the rules can't
and don't support it.
Jun 16 '07 #38

P: n/a
valentin tihomirov <V_*********@best.eewrote:
It's already been pointed out that you *can* use null as an argument.

Neither func(null), nor func(ref null) works. I have checked myself.
To what signature? Here's an example of func(null) working fine:

using System;

class Test
{
static void Main()
{
func(null);
}

static void func(object o)
{
}
}

As you haven't provided the signature of "func" it's hard to know
exactly what you're doing wrong. If func is declared with two
parameters, or a value type parameter, or a ref/out parameter then it
will certainly fail, but that's a different matter.
Again, how is this difference from passing by reference in C++?

Where do I tell that C# references are different from C++ references? I
was
speaking about the difference between "pointers" and "references"!
You need to understand the difference between *a* reference (which is
like a C++ pointer) and passing something *by* reference which is like
passing by reference in C++.

C++ references are also "like" C++ pointers. But not the same. They are
different. Nulls are not allowed where reference is required. That is the
difference.
The reason you can't do "ref null" is nothing to do with the value null
itself though - it's because you're trying to use a value rather than a
variable.

--
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
Jun 16 '07 #39

P: n/a
valentin tihomirov <V_*********@best.eewrote:
Yes, both "out" and "ref" require you to use an actual variable. This
is entirely reasonable given the purpose of ref, IMO.

But you cannot read the 'out' parameter in order to accoumplish the trick of
passing 'null' reference.
Do you remember how early on I asked you to describe what you were
trying to achieve *without referring to other languages*? I can't help
but feel this is still the only way forward in this discussion...

--
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
Jun 16 '07 #40

P: n/a
valentin tihomirov <V_*********@best.eewrote:
You _can_ pass null as an argument. You just can't pass null as an
argument for a "ref" parameter.
And it's important to note that it's not to do with it being null -
it's to do with being a *value* rather than a *variable*. If you try to
use the result of a method call as a ref parameter you fail in the same
way - ditto if you use a string literal.

To be relevant to the raised issue, it is important to note that the topic
is about passing arguemtns by pointers/references and that the 'null' is a
'literal'. That is why I state that 'null' is not allowed to pass as
argument.
Except it is - just not as an argument for a ref parameter.

--
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
Jun 16 '07 #41

P: n/a
Larry Smith <no_spam@_nospam.comwrote:
For two reasons:

1) out/ref arguments must be *variables* not values
2) The value of an out parameter isn't definitely assigned at the start
of a method, so you can't compare it with null.

You're explaining the language's existing rules which is fine, but I'm
questioning why it was done that way in the first place. Let's say I have a
function like "_splitpath" in the CRT. It takes a full path name as arg1 and
returns its drive letter, directory, file name and extension in the next
four "out" parameters.
And that's a pretty hideous design, when it comes to OO, isn't it? C#
is designed as an OO language, where you'd want to encapsulate those
output parameters in a type.

That occasionally makes it hard to use APIs which are completely non-
OO, as in this case.
I'm only interested in the directory for instance so
I want to pass "null" for the other "out" arguments. I can't do this however
which is very inconvenient. I'm forced to pass all "out" arguments IOW.
Someone might argue not to design methods like this but there's nothing
inherently wrong with it so it's ultimately the programmer's choice. It may
also prove more efficient in some cases, letting the function know it
doesn't have to carry out the extra work of retrieving all "out" parameters.
I'd say that's a pretty nasty way of letting the method know that - I'd
far prefer to use an option of what to retrieve, or an overload.
Nor do I have to create additional methods to retrieve each individual piece
of info or otherwise create an extra class to store all this data.
No, but that would be a more OO-approach, and a much tidier one IMO.
Sometimes I'm even just intersested in a function's return value
without caring about the "out" parameter(s). Barring any tangible
constraints on the language's ability to implement this feature, I
see no valid reason why the rules can't and don't support it.
I can't think of any way of doing this without losing some elegance.
What would happen if you *did* try to assign a value in method
accepting a ref/out parameter which had been called with null? If it
would go bang, that creates additional work for *every* method which
takes ref/out parameters, for one thing.

I rather like the inability to read an "out" parameter before it's been
definitely assigned in the method - it makes it very simple to describe
the behaviour and the requirement that an out parameter is definitely
assigned before a method terminates normally.

This occasionally makes it harder to work with non-OO APIs, but I'd
rather that was penalised in favour those who *are* taking an OO
approach than vice versa.

--
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
Jun 16 '07 #42

P: n/a
I completely disagree. There's nothing inherently ugly about it at all. It's
very clean in code and C/C++ developers have been using it for decades. Most
of the time you're dealing with one or two "out" parameters only so passing
"null" is a very quick and convenient (and consistent) way to tell any
function not to fill something in. It's highly legible (self-describing) and
no extraneous flags or properties are required to control what you want
(which means more work and more code). As for it being error-prone, that
argument is almost groundless in practice. It's no more error-prone than
passing null for a non-out parameter if the function isn't designed to
handle it. Any function should be prepared to handle null even if it means a
simple Assert at the very least. For an "out" parmeter, one simple check for
null is all that's required to make it optional. I've been in the coding
trenches for almost 25 years and can't recall anytime I had an issue with
this.
Jun 16 '07 #43

P: n/a
valentin tihomirov wrote:
As explained in "Using pointers vs. references"
http://groups.google.ee/group/borlan...294c7b02e8faca ,
the pointers are allowed to be null, while references must refer an existing
variable of required type. The null is normally used for making optional
parameters. But there is no way to pass null reference in C#. Something is
missing.
That's right, there's no way to verifiably pass a reference to an
invalid location logically corresponding to null in .NET. It could be
implemented - and memory safety preserved - since the hardware would
still trigger access violation exceptions, but it isn't.

It's not a big deal, though. The benefit of being able to cause null
reference exceptions when assigning to parameters, or avoid having to
create a dummy local for passing into a routine, is pretty marginal.

-- Barry

--
http://barrkel.blogspot.com/
Jun 16 '07 #44

P: n/a
valentin tihomirov wrote:
Since a "ref" parameter is essentially the same as C++'s "&" by-reference

THEY ARE NOT !!!
There's no need to shout, and C# / .NET's concept of a ref parameter is
a limited subset of C++'s '&' reference parameters. They're not the
same, true, but they are strongly related.
parameter, and since the "ref" parameter type (along with "out" which is a
special case of "ref") is the only situation in which your complaint about
not being able to pass null is true, _that_ is "where you tell that C#
references are different from C++ references".

Show me where I tell that Delphi/C++ references are different from C#
references? I repeat once again, THESE ARE POINTERS WHICH ARE DIFFERENT FROM
REFERENCES !!!
References are implemented on the machine as pointers. The CPU has no
model for a 'reference'; only a memory address, i.e. pointer. Higher
levels, such as Delphi, C++ or .NET, make a distinction for type safety
and (in the case of .NET) memory safety reasons.
Importing a dll function, one may declare their arguments wheter as poitners
of references. Both will work, because internal mechanics, the
implementation is the same. But reference prevents passing 'null'. The
compiler will not allow. They must refer existing object.
Yes. However, when you see an API function declaration in Delphi that
uses 'var' or 'out' in the parameter declaration list where the API
documentation indicates that the parameter is actually optional, the
declaration is in fact in error - it should have been declared to take a
pointer instead of a reference.

Sure, you can use something like PFoo(nil)^ to pass a reference to an
invalid null location, and thereby get around the bug in the declaration
- but you can't do that in C# / .NET. Microsoft could have implemented
it, but they didn't. That's the way it is; it's not a big loss.

-- Barry

--
http://barrkel.blogspot.com/
Jun 16 '07 #45

P: n/a

"Austin Ehlers" <austin.ehlers.spam.@gmail.comwrote in message
news:cb********************************@4ax.com...
On Fri, 15 Jun 2007 15:39:24 -0700, "Peter Duniho"
<Np*********@nnowslpianmk.comwrote:
>>On Fri, 15 Jun 2007 15:17:36 -0700, Austin Ehlers
<austin.ehlers.spam.@gmail.comwrote:
>>Why not just use the return value, like String does? If you have
multiple parameters that need to be changed, then it is usually bad
code, trying to do too much in one method, and should be refactored
into a better design.

I agree that for immutable types, the best solution is usually to return a
new instance as the result from a method, rather than using a "ref"
parameter. However, consider situations like TryParse where you want to
return more than one value: the new instance and a result code of some
sort, for example. Are you suggesting that the TryParse pattern is
indicative of poor design?

It's true that these situations aren't very common. But I wouldn't go so
far as to say that one never needs to pass reference variables by
reference.

But is that a reference type? Besides IPAddress.TryParse, they're all
structs. (Notice I said "usually bad, trying to do too much in one
method". Parsing a string into a type is a common, single idea).
Dictionary`2.TryGetValue, anyone?
>
>>Seeing a reference type passed by-ref in code, particularly from
someone new to C#/.NET, is like seeing a class with a finalizer: it's
occasionally right, but not often.

"Occasionally right" being the operative phrase, IMHO. You wrote "Please,
show me where a ref-by-ref is needed in C#/.NET". I interpreted Ben's
reply simply as doing just that, showing you where it's needed.

And that's fine. I'm just trying to show the OP that things are
different in C# than C/C++, and trying to use C-style code will lead
to a bad design.

Austin
Jun 16 '07 #46

P: n/a

"Jon Skeet [C# MVP]" <sk***@pobox.comwrote in message
news:MP*********************@msnews.microsoft.com. ..
Ben Voigt [C++ MVP] <rb*@nospam.nospamwrote:
While I can think of some reasons why pass-by-ref of reference types is
sometimes useful, I can't make head or tail of your reply,
unfortunately. However, I suspect I could learn something if you'd be
willing to elaborate.

The argument against pass ref class by-ref seems to be that you should
modify the referenced class in place. That isn't possible for immutable
types, like string. To return string data by reference, you can pass a
string variable by-ref, (or use a StringBuilder).

Agreed.
>Copy-on-write: If you aren't allowed to modify the object in-place, but
have
to clone it in order to change it, then the caller's reference needs to
be
updated to the new copy. Again, ref-by-ref. strings are actually a
subset
of this case.

Right, I 'm with you.
>If the resulting value has to compare equal by referential equality every
time it is returned, then you need to set the caller's reference equal to
your own. Again, ref-by-ref.

Hmm... that may be an idiom I've never come across. The first two make
absolute sense (even if they're fairly rarely required), but this one
is outside my experience.
Well, for example, Dictionary`2.TryGetValue has to return the same object
every time. It's not sufficient to copy the data into a caller-provided
object. There may be cases where the method has enough information to copy
(Dictionary couldn't even if it wanted to), but you want to share the same
object every time anyway. I think this is part of the Flyweight pattern.
>
--
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
Jun 16 '07 #47

P: n/a
On Fri, 15 Jun 2007 20:21:08 -0700, Austin Ehlers
<austin.ehlers.spam.@gmail.comwrote:
But is that a reference type? Besides IPAddress.TryParse, they're all
structs.
Which are all structs? I know you're not claiming to have surveyed every
instance of a method named "TryParse" that anyone has ever written in C#.
And there's certainly no requirement that one limit the use of TryParse()
with structs.

I see no reason at all to restrict the TryParse semantics or similar to
structs. Just because in the .NET Framework itself they are (almost) all
structs, that's no reason to think you can't still do the same with
classes.
(Notice I said "usually bad, trying to do too much in one
method". Parsing a string into a type is a common, single idea).
You also sais "Please, show me where a ref-by-ref is needed in C#/.NET"
and I believe it was to that than Ben was responding. He did exactly as
you asked.
>"Occasionally right" being the operative phrase, IMHO. You wrote
"Please,
show me where a ref-by-ref is needed in C#/.NET". I interpreted Ben's
reply simply as doing just that, showing you where it's needed.

And that's fine. I'm just trying to show the OP that things are
different in C# than C/C++, and trying to use C-style code will lead
to a bad design.
Well, ignoring for the moment that your reply to Ben's post _appears_ to
me to indicate that it's not "fine"...

There's really nothing about this issue that distinguishes C++ from C#.
The same exact question regarding whether it's good to have by-reference
parameters exists in either language, and has the same arguments in favor
of and against.

Pete
Jun 16 '07 #48

P: n/a
On Sat, 16 Jun 2007 05:53:38 -0700, valentin tihomirov
<V_*********@best.eewrote:
Larry grasped it very well. But the correct answer, which I assumed in
the
OP, is not because C# references are the same as references in other
languages. Doing so is not allowed because the pointers, which are
allowed
to refer any areas of memory where no valid objects exist including
address
0, are not supported in C#.
That makes no sense at all. The question of "ref" parameters has exactly
zero to do with the implementation of references vs pointers. You are
trying to apply some nonsensical, irrelevant aspect of the data type
implementation in debating a higher-level language construct.

Pete
Jun 16 '07 #49

P: n/a

"Larry Smith" <no_spam@_nospam.comwrote in message
news:%2****************@TK2MSFTNGP04.phx.gbl...
>>>You can't use a null for a reference parameter in C++ either. The
following generates a compile error, just as the "ref" parameter example
you gave for C# does:

Yes you can. You do have to pass the correct type, however.

void Func(int &i)
{
}

void Caller()
{
Func(*(int*)nullptr);
}

It's a very bad idea, true, but people who use references instead of
pointers simply because "I would have to check for NULL pointers, and
references can't be NULL" are simply misinformed.

Not only is it bad, it's undefined behaviour so it doesn't qualify as
valid C++. You can't legally dereference a null pointer nor is a null
reference legally possible.
Is creating a reference from a pointer defined as dereferencing that
pointer, even though no access through that pointer occurs until much later?

Jun 16 '07 #50

76 Replies

This discussion thread is closed

Replies have been disabled for this discussion.