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

"ref object a" <> "ByRef a As Object" ???

P: n/a
GDay all,

Something seems odd to me....
I wrote a simple C# function

public void bind(ref object a, ref object b, bool atob)
{
if(atob)
b = a;
else
a = b;
}

I call it from a windows app.

string data = "moo";
bind(ref (object)this.Text, ref (object)data, false);

As I expected I got Error CS1510 "A ref or out argument must be an
lvalue".
Here is what I didnt't expect, when I wrote a vb.net equivilant:

Public Sub bind(ByRef a As Object, ByRef b As Object, ByVal atob As
Boolean)
If (atob) Then
b = a
Else
a = b
End If
End Sub

and call it from a windows app:

Dim data As String = "moo"
bind(Me.Text, data, False)

Not only did it compile it also executed and worked - the forms title
was changed to "moo".

Why does VB.NET not spit the dummy?
Is it possible to coax C# into doing whatever vb did?

-DM
Jul 21 '05 #1
Share this Question
Share on Google+
22 Replies


P: n/a
Dr Duck <sh********@optusnet.com.au> wrote:

<snip>
Here is what I didnt't expect, when I wrote a vb.net equivilant:

Public Sub bind(ByRef a As Object, ByRef b As Object, ByVal atob As
Boolean)
If (atob) Then
b = a
Else
a = b
End If
End Sub

and call it from a windows app:

Dim data As String = "moo"
bind(Me.Text, data, False)

Not only did it compile it also executed and worked - the forms title
was changed to "moo".

Why does VB.NET not spit the dummy?
Is it possible to coax C# into doing whatever vb did?


I've had a look at what VB.NET does under the covers, and basically it
creates temporary objects, passes those by reference, and then sets
data and Me.Text to the results afterwards. Utterly horrible, if you
ask me... but it only does it that way if the parameters are either
properties or subtypes of the formal parameter types.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jul 21 '05 #2

P: n/a
Thanks Mate

I agree this "late bound tempory object" [made up term] thing sounds Horrible

I can't see the rational behind it

It sounds like it would cause a lot of problems in a multi threaded app
- assignment after the function call exits not being semaphore aware..
- a process comunicating to another it had modified the object referenced as a parameter
but the modification is not apparent as the process has not exited yet...

-DM
Jul 21 '05 #3

P: n/a
Hi Jon,

I was yesterday suprissed reading that you did in the thread C# learner give
an advice to look for VB.net, that I never did expect, however you sees how
things can change. (no comments needed, I most probably know them already)

:-)

However when this message would come in the newsgroup languages.VB it would
get a lot of comments.

1. passing "by ref" from an Object, did you not try once to get me in a
discussion about boxing?.
2. passing as an Object
3. not Option Strict On.

I understand that it is a theoretical question, however I did want to add
this, because I did not see it in your comment, while this program will run
probably 10 times as slow as it could be.

What is something you make me always attent on when I forget by instance to
Xor a bit and do an "if" instead.

(And this part is not the area I like)

:-)

Cor
Public Sub bind(ByRef a As Object, ByRef b As Object, ByVal atob As
Boolean)
If (atob) Then
b = a
Else
a = b
End If
End Sub

Jul 21 '05 #4

P: n/a
Cor Ligthert <no**********@planet.nl> wrote:
However when this message would come in the newsgroup languages.VB it would
get a lot of comments.

1. passing "by ref" from an Object, did you not try once to get me in a
discussion about boxing?.
Um, can't remember... is it important? There's no boxing going on here,
as there are no value types.
2. passing as an Object
What about it?
3. not Option Strict On.
Ah - didn't check that one. (Silly default, to have it off.) Yup, that
improves things *slightly*. It doesn't stop you from passing a property
by reference, although it does stop you from passing a string parameter
by reference to a method accepting the parameter as an object by
reference. In other words, it gets rid of half of the nastiness, but
not all of it.
I understand that it is a theoretical question, however I did want to add
this, because I did not see it in your comment, while this program will run
probably 10 times as slow as it could be.
I'm not sure I'd go along with that bit. It's not like it's using
reflection anywhere, for instance - it's just fetching a property and
assigning it again afterwards, which may *sometimes* be expensive, but
certainly doesn't have to be.
What is something you make me always attent on when I forget by instance to
Xor a bit and do an "if" instead.

(And this part is not the area I like)


No idea what you meant by that, but never mind.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jul 21 '05 #5

P: n/a
Hi Jon,
1. passing "by ref" from an Object, did you not try once to get me in a
discussion about boxing?.

This are not the subjects (area) I like I said, so when I am wrong, I can
this time (at start) only believe you, however in VB is an object normaly
passed by value.

Because that value is its reference. I thought that when you do a passing by
reference, you are boxing that value (which is the reference).

However I am not sure about it, because I never would think about to pass a
reference of a reference.

Cor
Jul 21 '05 #6

P: n/a
Cor Ligthert <no**********@planet.nl> wrote:
1. passing "by ref" from an Object, did you not try once to get me in a
discussion about boxing?.
This are not the subjects (area) I like I said, so when I am wrong, I can
this time (at start) only believe you, however in VB is an object normaly
passed by value.

Because that value is its reference. I thought that when you do a passing by
reference, you are boxing that value (which is the reference).
No, you aren't. Boxing is an entirely different concept. Boxing takes a
value type, and creates a new object on the heap containing that value.
It has nothing to do with pass-by-reference semantics.
However I am not sure about it, because I never would think about to pass a
reference of a reference.


Why not? It makes perfect sense in some situations.

See http://www.pobox.com/~skeet/csharp/parameters.html for more general
discussion of what pass-by-reference and pass-by-value mean, admittedly
in C# terms.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jul 21 '05 #7

P: n/a
Hi Jon,

Because about some things I readed from Jay B Harlow I am not sure of your
message.

However I cannot deny it now. So maybe, ( because it does not intrest me
that much) I will investigate it deeper and come back on this subject.

However it was intresting that you do not agree with it, makes investigating
maybe something I will do.
Why not? It makes perfect sense in some situations.


I have done in past a lot of references of pointers, however until now I see
in VB.net no pratical use of it.

Cor
Jul 21 '05 #8

P: n/a
Cor Ligthert <no**********@planet.nl> wrote:
Because about some things I readed from Jay B Harlow I am not sure of your
message.
Which things, out of interest? Which thread?
However I cannot deny it now. So maybe, ( because it does not intrest me
that much) I will investigate it deeper and come back on this subject.

However it was intresting that you do not agree with it, makes investigating
maybe something I will do.


I'll look at it myself - if you could let me know what Jay's said.
Why not? It makes perfect sense in some situations.


I have done in past a lot of references of pointers, however until now I see
in VB.net no pratical use of it.


Here's an example I've used before:

public void SplitName (string wholeName, out string firstName,
out string lastName)

("out" and "ref" parameters are very similar, I hope you'll agree)

So for instance:

string first;
string last;

SplitName ("Jon Skeet", out first, out last)

would end up with first="Jon" and last="Skeet".

I'm sure you can think of similar situations.

Personally I don't use out/ref parameters very often anyway, but when I
do they're just as likely to be reference types as value types.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jul 21 '05 #9

P: n/a
> public void bind(ref object a, ref object b, bool atob)
{
if(atob)
b = a;
else
a = b;
}

I call it from a windows app.

string data = "moo";
bind(ref (object)this.Text, ref (object)data, false);

As I expected I got Error CS1510 "A ref or out argument must be an
lvalue".

The question is: Why isn't that allowed?

--
cody

[Freeware, Games and Humor]
www.deutronium.de.vu || www.deutronium.tk
Jul 21 '05 #10

P: n/a
cody <pl*************************@gmx.de> wrote:
As I expected I got Error CS1510 "A ref or out argument must be an
lvalue".


The question is: Why isn't that allowed?


Because it would be completely against the way that pass by reference
works (when not considering remoting, etc), namely that the method
being called ends up using the same memory slot for the formal
parameter as for the actual parameter that the calling method passed
in.

I for one am glad that C# *doesn't* allow such behaviour.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jul 21 '05 #11

P: n/a
> > > As I expected I got Error CS1510 "A ref or out argument must be an
lvalue".


The question is: Why isn't that allowed?


Because it would be completely against the way that pass by reference
works (when not considering remoting, etc), namely that the method
being called ends up using the same memory slot for the formal
parameter as for the actual parameter that the calling method passed
in.

I for one am glad that C# *doesn't* allow such behaviour.

I understand that a ref argument has to be an lvalue but I don't understand
why a cast expression is not lvalue.

void Foo(ref object obj)
{
obj=null;
}

string s = "test";
Foo(ref(object)s);

Why isn't that allowed? Has the casted object s a new address or what?
In c++,

void Foo(int ** n)
{
*n=0;
}

float * f = new float;
*f = 1.0f;
Foo((int**)&f);

worked, and that is semantically exactly the same: passing a reference as
reference.

--
cody

[Freeware, Games and Humor]
www.deutronium.de.vu || www.deutronium.tk
Jul 21 '05 #12

P: n/a
cody <pl*************************@gmx.de> wrote:
Because it would be completely against the way that pass by reference
works (when not considering remoting, etc), namely that the method
being called ends up using the same memory slot for the formal
parameter as for the actual parameter that the calling method passed
in.

I for one am glad that C# *doesn't* allow such behaviour.
I understand that a ref argument has to be an lvalue but I don't understand
why a cast expression is not lvalue.


It's because it's the result of an operation, it's not a variable on
its own. It's just like (i+1) isn't an lvalue, but i is (assuming i is
a variable, of course).

You can't assign to cast variables elsewhere, can you? You can't say:

((object)s)="hello";

or (worse)

((object)s)=new object();
void Foo(ref object obj)
{
obj=null;
}

string s = "test";
Foo(ref(object)s);

Why isn't that allowed? Has the casted object s a new address or what?
Consider if it were allowed, but if Foo were written as:

void Foo (ref object obj)
{
obj = Encoding.ASCII;
}

Now, that would surely have to throw an exception, wouldn't it? But
would we really want the overhead of checking type safety every time we
assigned a new value to obj?
In c++,

void Foo(int ** n)
{
*n=0;
}

float * f = new float;
*f = 1.0f;
Foo((int**)&f);

worked, and that is semantically exactly the same: passing a reference as
reference.


Well, it's actually passing a pointer to a pointer by value, but yes,
the effect is much the same. I don't know whether or not C++ would
actually let you pass *by reference* in a dodgy way though.

But yes, C++ lets you shoot yourself in the foot. It lets you pass
pointers around and then assign completely different types willy-nilly.
That's one of the reasons I use C# rather than C++. I'm quite happy
with it keeping me safe.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jul 21 '05 #13

P: n/a
Thanks Joh et al,

your first reply answed the question.
Somehow my last reply here did not work :(
I for one am glad that C# *doesn't* allow such behaviour.

me too, but a object proxy to a accesor would be an interesting
tool.....

I am disturbed by vbs behaviour and can't see the reasoning behing it,
can anbodey see the logic?

I am curious how the vb tempory-object-wanabee-a-reference would work
in multitreaded apps.

Some senarios where I see porblems:

tread1 modifies a byref object and comunicates to thread 2 that the
object has been modified and is now ready for thread2s use. However
thread 2 changes the object before thread1 exits. End result thread 1
exits and the object is now modified to the state which tread two was
expecting and the work of thread2 is undone.

The post function exit binding may not adhear to our semaphore scemm
(functions tend to release semaphores before exiting). Possible
solution semaphore to byref parameter is also implemented as a byref
parameter ensuring a lock during the post function stuff...

thanks
-DM
Jul 21 '05 #14

P: n/a
Hi

When you look at the intention from the message in this thread from me to
Jon, than you can see that VB.net does not always allow this behaviour

I think that for compatible reasons with VB6 there is a feature to do those
things with late binding. That is in VB.net 2002 and VB.net 2003 default set
to Off. I hope it will be in VB.net 2005 set to standard On. However they
are adding a lot of old VB6 things, so you never know.

In this dotNet newsgroup is always told by the regulars to the people who
use VB.net to set that feature as fast as possible to On because it gives to
much change on errors in runtime.

Jon told he forgot to mention this and did correct that only in the thread
where we where discussing that

With Option Strict On in VB.net the behaviour is the same as C#.

Cor
Jul 21 '05 #15

P: n/a
> > void Foo(ref object obj)
{
obj=null;
}

string s = "test";
Foo(ref(object)s);

Why isn't that allowed? Has the casted object s a new address or what?


Consider if it were allowed, but if Foo were written as:

void Foo (ref object obj)
{
obj = Encoding.ASCII;
}

Now, that would surely have to throw an exception, wouldn't it? But
would we really want the overhead of checking type safety every time we
assigned a new value to obj?

OK I understand, that makes sense.

--
cody

[Freeware, Games and Humor]
www.deutronium.de.vu || www.deutronium.tk
Jul 21 '05 #16

P: n/a
Cor Ligthert <no**********@planet.nl> wrote:
With Option Strict On in VB.net the behaviour is the same as C#.


No it's not - as I said in the message, VB.NET still allows you to pass
a property by reference with option strict on, it just doesn't allow
the actual parameter type to be different from the formal parameter
type.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jul 21 '05 #17

P: n/a
Hi Jon,

Did you try the complete sample in VB with option strict on?

Cor
Jul 21 '05 #18

P: n/a
Cor Ligthert <no**********@planet.nl> wrote:
Did you try the complete sample in VB with option strict on?


Yes, and that didn't work because of the type issue. However, I then
tried this:

Option Strict On

Imports System
Imports System.Windows.Forms

Class Test
Public Shared Sub bind(ByRef a As String, _
ByRef b As String, _
ByVal atob As Boolean)
If (atob) Then
b = a
Else
a = b
End If
End Sub
Public Shared Sub Main()
Dim data As String = "moo"
Dim f as New Form
bind(f.Text, data, False)
Console.WriteLine (f.Text)
End Sub

End Class

That shows a property being passed by reference, which you can't do in
C#.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jul 21 '05 #19

P: n/a
Hi Jon,
Public Shared Sub bind(ByRef a As String, _
ByRef b As String, _
ByVal atob As Boolean)


You did change it so much that it almost looks like this sample you showed
me
public void SplitName (string wholeName, out string firstName,
out string lastName)


("out" and "ref" parameters are very similar, I hope you'll agree)

What is wrong with that (however I would not use it only to move a value)

Cor
Jul 21 '05 #20

P: n/a
Cor Ligthert <no**********@planet.nl> wrote:
Public Shared Sub bind(ByRef a As String, _
ByRef b As String, _
ByVal atob As Boolean)


You did change it so much that it almost looks like this sample you showed
me
public void SplitName (string wholeName, out string firstName,
out string lastName)


("out" and "ref" parameters are very similar, I hope you'll agree)

What is wrong with that (however I would not use it only to move a value)


Nothing. You've snipped the piece of code which is problematic:

Dim data As String = "moo"
Dim f as New Form
bind(f.Text, data, False)

The problem is passing f.Text by reference, as it's a property, not a
variable. It causes the VB.NET compiler to do nasty stuff to add a
temporary local variable, fetch f.Text into it, pass the local variable
by reference, and then set f.Text to the value of the temporary local
variable afterwards. Icky.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jul 21 '05 #21

P: n/a
Hi Jon,

Dim data As String = "moo"
Dim f as New Form
bind(f.Text, data, False)

The problem is passing f.Text by reference, as it's a property, not a
variable. It causes the VB.NET compiler to do nasty stuff to add a
temporary local variable, fetch f.Text into it, pass the local variable
by reference, and then set f.Text to the value of the temporary local
variable afterwards. Icky.


I saw that of course (not how it is done), but what is wrong with that added
intelligence. The string itself does the same it is immutable, so the
reference should change and that is done as well in VB.net as in C#.

:-)

Cor

Jul 21 '05 #22

P: n/a
Cor Ligthert <no**********@planet.nl> wrote:
The problem is passing f.Text by reference, as it's a property, not a
variable. It causes the VB.NET compiler to do nasty stuff to add a
temporary local variable, fetch f.Text into it, pass the local variable
by reference, and then set f.Text to the value of the temporary local
variable afterwards. Icky.


I saw that of course (not how it is done), but what is wrong with
that added intelligence. The string itself does the same it is
immutable, so the reference should change and that is done as well in
VB.net as in C#.


It's actually got nothing to do with immutability. The reason it's
"wrong" is:

o It involves exactly one "read" of the property and one "write" of the
property - despite the fact that the method may be reading and writing
the parameter several times during its course.

o It hides the fact that it's doing this single read and single write.
If you're forced to do it explicitly, it's much more obvious what's
going on.

o As Dr Duck has said, it could have nasty effects on multi-threaded
scenarios, where one thread *thinks* it has actually set a value, as
it's set the value of a parameter which has been passed by reference.
In actual fact, it's just setting the value of the hidden local
variable. Unless you *know* what's happening, you could get into all
sorts of bother working out why things aren't working.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jul 21 '05 #23

This discussion thread is closed

Replies have been disabled for this discussion.