Properties - C# vs VB - ??

  • Thread starter Thread starter Timothy
  • Start date Start date
T

Timothy

Hi,
I was looking over some differences between C# and VB code today and noticed
that the set method in properties act completely different. C# values are
passed by reference, and VB values are passed by value... Am I right? Why is
there such a big difference in implementation of properties?
 
Timothy said:
Hi,
I was looking over some differences between C# and VB code today and
noticed that the set method in properties act completely different. C#
values are passed by reference, and VB values are passed by value... Am
I right? Why is there such a big difference in implementation of
properties?

Hm, not sure I understand. In C#, setting a property passes the value,
not a reference to the new value. What exactly are you describing here?
 
Well, no, you are wrong.
The simple answer would be that struct instances are passed by value while
class instances are passed by readonly reference.
It doesn't depend on the lanugage.
 
Lasse Vågsæther Karlsen said:
Hm, not sure I understand. In C#, setting a property passes the value, not
a reference to the new value. What exactly are you describing here?

Maybe I'm doing something wrong? Running this code produces an output of
"2". Assigning the string, "1", within the Sample instance then assigning
the property within SampleWithProperty as the Sample instance... Then
changing the Sample instance's string value to "2".... the string of the
Sample instance kept by the SampleWithProperty instance SHOULD be "1",
shouldn't it?

class Program
{
static void Main(string[] args)
{
Sample s = new Sample();
SampleWithProperty swp = new SampleWithProperty();

s.a = "1";
swp.b = s;
s.a = "2";
Console.WriteLine(swp.b.a); // prints "2"
}
}

class Sample
{
public string a;
}

class SampleWithProperty
{
public Sample b { get; set; }
}
 
Timothy said:
Maybe I'm doing something wrong? Running this code produces an output of
"2". Assigning the string, "1", within the Sample instance then assigning
the property within SampleWithProperty as the Sample instance... Then
changing the Sample instance's string value to "2".... the string of the
Sample instance kept by the SampleWithProperty instance SHOULD be "1",
shouldn't it?

No, because they both refer to the same instance of Sample. Only one
instance of it is ever created.

See
http://pobox.com/~skeet/csharp/parameters.html
and
http://pobox.com/~skeet/csharp/references.html
for information about the difference between reference types and value
types.
 
Just did the same example in VB, but it had the same effect... I got a
little confused because the Set method had a ByVal keyword attached (which
still confuses me). Maybe someone can explain this to me. Here is the code
btw:

Module Module1

Sub Main()
Dim s As New Sample
Dim swp As New SampleWithProperty

s.a = "1"
swp.b = s
s.a = "2"
Console.WriteLine(swp.b.a)
End Sub

End Module

Class Sample
Public a As String
End Class

Class SampleWithProperty

Private _b As Sample
Public Property b() As Sample
Get
Return _b
End Get
Set(ByVal value As Sample)
_b = value
End Set
End Property

End Class
 
Timothy said:
Lasse Vågsæther Karlsen said:
Hm, not sure I understand. In C#, setting a property passes the value,
not a reference to the new value. What exactly are you describing here?

Maybe I'm doing something wrong? Running this code produces an output of
"2". Assigning the string, "1", within the Sample instance then
assigning the property within SampleWithProperty as the Sample
instance... Then changing the Sample instance's string value to "2"....
the string of the Sample instance kept by the SampleWithProperty
instance SHOULD be "1", shouldn't it?

class Program
{
static void Main(string[] args)
{
Sample s = new Sample();
SampleWithProperty swp = new SampleWithProperty();

s.a = "1";
swp.b = s;
s.a = "2";
Console.WriteLine(swp.b.a); // prints "2"
}
}

class Sample
{
public string a;
}

class SampleWithProperty
{
public Sample b { get; set; }
}

No, this has nothing to do with properties.

A class is a reference type. A variable, property, field, whatever you
pick, will hold a pointer to a place in memory where the actual class it.

This type of code:

Sample s1 = new Sample();
Sample s2 = s1;

does not produce two copies of an object of Sample. It produces two
references to the one object.

Let me explain it another way.

A house is built from a blueprint, in a location and given an address.
(blueprint is the class, the house is the object, the address is the
reference).

It doesn't matter how many pieces of paper you write down the address
to, if you go to the house and rearrange the furniture, the house from
all those addresses will still be just the one house, and it doesn't
matter which paper you pick, they all lead to the same one house. To an
observer that only reads the address, goes to the house, and doesn't
look at the surroundings, it might look like he has many pieces of paper
that leads to identical (but separate) houses, but he's in reality just
visiting the same house over and over again.

A value type, which is used for structs and all the base types for
numbers (among other things), is not a pointer, and thus the value
itself is copied, which means that each value is separate. You can,
similar to the one above, think of it like a number on a piece of paper.
If you copy the number to a new paper, but then alter the number on the
original paper afterwards, the copy is still as it was when it was made,
ie. unchanged. Now you have two pieces of papers with different numbers
on them.

Strings are something inbetween (simplified explanation). They are pure
reference types, which means that a variable holding a string holds a
pointer to a location in memory where the string data is stored. The
difference is that string objects in .NET are made immutable, which mean
that once they are created, they will never change. Thus, if you
construct a new string, it will be in a different location in memory,
and thus have a new address. If you think of the house, instead of
rearranging the furniture, "changing a string" means constructing a new,
almost identical house, except for the changes from the original.

This code:

String s1 = "test";
String s2 = s1 + "!";

constructs two string objects, that are different.

All this is true also for Visual Basic.NET and other .NET languages. If
you have evidence to the contrary, I suggest you post it because I'm
confident that there's something else that is different in the VB
solution as well, that makes you observe different things.

Hope all of this was clear, if not, poke holes in it and ask more
questions. If I incorrectly assumed you didn't know all this, I
apologize for the lecture :)
 
Lasse Vågsæther Karlsen said:
No, this has nothing to do with properties.

A class is a reference type. A variable, property, field, whatever you
pick, will hold a pointer to a place in memory where the actual class it.

This type of code:

Sample s1 = new Sample();
Sample s2 = s1;

does not produce two copies of an object of Sample. It produces two
references to the one object.

Let me explain it another way.

A house is built from a blueprint, in a location and given an address.
(blueprint is the class, the house is the object, the address is the
reference).

It doesn't matter how many pieces of paper you write down the address to,
if you go to the house and rearrange the furniture, the house from all
those addresses will still be just the one house, and it doesn't matter
which paper you pick, they all lead to the same one house. To an observer
that only reads the address, goes to the house, and doesn't look at the
surroundings, it might look like he has many pieces of paper that leads to
identical (but separate) houses, but he's in reality just visiting the
same house over and over again.

A value type, which is used for structs and all the base types for numbers
(among other things), is not a pointer, and thus the value itself is
copied, which means that each value is separate. You can, similar to the
one above, think of it like a number on a piece of paper. If you copy the
number to a new paper, but then alter the number on the original paper
afterwards, the copy is still as it was when it was made, ie. unchanged.
Now you have two pieces of papers with different numbers on them.

Strings are something inbetween (simplified explanation). They are pure
reference types, which means that a variable holding a string holds a
pointer to a location in memory where the string data is stored. The
difference is that string objects in .NET are made immutable, which mean
that once they are created, they will never change. Thus, if you construct
a new string, it will be in a different location in memory, and thus have
a new address. If you think of the house, instead of rearranging the
furniture, "changing a string" means constructing a new, almost identical
house, except for the changes from the original.

This code:

String s1 = "test";
String s2 = s1 + "!";

constructs two string objects, that are different.

All this is true also for Visual Basic.NET and other .NET languages. If
you have evidence to the contrary, I suggest you post it because I'm
confident that there's something else that is different in the VB solution
as well, that makes you observe different things.

Hope all of this was clear, if not, poke holes in it and ask more
questions. If I incorrectly assumed you didn't know all this, I apologize
for the lecture :)

Thanks for the very informative lecture :-) You have answered my question,
for the most part. If you know a little VB, you may be able to finish it
off. In the code I posted just before (the VB code) I mentioned that the
ByVal keyword confused me a little... This is what was giving me grief. I
don't understand why the ByVal keyword is required, especially when it
should be ByRef... Maybe I don't understand those keywords enough yet...

Public Property b() As Sample
Get
Return _b
End Get
Set(ByVal value As Sample) ''''<<<<
_b = value
End Set
End Property
 
Timothy said:
Thanks for the very informative lecture :-) You have answered my
question, for the most part. If you know a little VB, you may be able to
finish it off. In the code I posted just before (the VB code) I
mentioned that the ByVal keyword confused me a little... This is what
was giving me grief. I don't understand why the ByVal keyword is
required, especially when it should be ByRef... Maybe I don't understand
those keywords enough yet...

Public Property b() As Sample
Get
Return _b
End Get
Set(ByVal value As Sample) ''''<<<<
_b = value
End Set
End Property

ByVal simply means that the method can't pass a new value back, any
changes it makes locally (inside the method) is local, won't affect the
code that called it.

In C# you got something similar, but the "by value" calling convention
is done by default, no keyword for it. Instead of the ByRef keyword,
there is the ref keyword.

This has nothing to do with reference types and value types. Let me
explain it with some C# code.

Assume you have the following code:

public void Change(Sample s)
{
s.a = "Test";
}

This method is passed a reference to the object, and can easily change
the contents of that object. Think of it as passing a piece of paper
with an address to that house I mentioned. The method is free to go to
the house and rearrange the furniture.

However, what it cannot do is change the piece of paper and pass it back
to me so that when I get the paper back (ie. you're done with the
method), there is a different address on the paper.

With a reference parameter, ByRef in VB and ref in C#, you can do that.
In both cases you're free to visit the object and modify it, but with a
reference parameter you can give a new object back to the caller.

Example:

public void Change(Sample s)
{
s.a = "Test";
s = new Sample();
s.a = "Test 2";
}

In this case, the method first modifies the Sample object it was given,
and then constructs a new Sample object and modifies its "s" parameter.
However, the following code:

Sample s1 = new Sample();
Change(s1);
Debug.WriteLine(s1.a);

will output "Test" to the output window, not "Test 2", as this new
object is never given back and thus the reference (address) stored in s1
doesn't change. I'm still refering to the original Sample object I
constructed.

If, on the other hand, you modify Change to pass the "s" parameter by
reference, like this:

public void Change(ref Sample s)

then the output window will now contain "Test 2", as the s1 variable in
the code that called Change is modified.

This means that you now have the following terms to cope with:

Value types - copying one makes a new separate value
Reference types - copying one makes a new reference to the same object
Reference parameters - modifying one in the method changes the variable
in the code that called it
 
Lasse Vågsæther Karlsen said:
ByVal simply means that the method can't pass a new value back, any
changes it makes locally (inside the method) is local, won't affect the
code that called it.

In C# you got something similar, but the "by value" calling convention is
done by default, no keyword for it. Instead of the ByRef keyword, there is
the ref keyword.

This has nothing to do with reference types and value types. Let me
explain it with some C# code.

Assume you have the following code:

public void Change(Sample s)
{
s.a = "Test";
}

This method is passed a reference to the object, and can easily change the
contents of that object. Think of it as passing a piece of paper with an
address to that house I mentioned. The method is free to go to the house
and rearrange the furniture.

However, what it cannot do is change the piece of paper and pass it back
to me so that when I get the paper back (ie. you're done with the method),
there is a different address on the paper.

With a reference parameter, ByRef in VB and ref in C#, you can do that. In
both cases you're free to visit the object and modify it, but with a
reference parameter you can give a new object back to the caller.

Example:

public void Change(Sample s)
{
s.a = "Test";
s = new Sample();
s.a = "Test 2";
}

In this case, the method first modifies the Sample object it was given,
and then constructs a new Sample object and modifies its "s" parameter.
However, the following code:

Sample s1 = new Sample();
Change(s1);
Debug.WriteLine(s1.a);

will output "Test" to the output window, not "Test 2", as this new object
is never given back and thus the reference (address) stored in s1 doesn't
change. I'm still refering to the original Sample object I constructed.

If, on the other hand, you modify Change to pass the "s" parameter by
reference, like this:

public void Change(ref Sample s)

then the output window will now contain "Test 2", as the s1 variable in
the code that called Change is modified.

This means that you now have the following terms to cope with:

Value types - copying one makes a new separate value
Reference types - copying one makes a new reference to the same object
Reference parameters - modifying one in the method changes the variable in
the code that called it

Wow, thank you! I understand it all now.
 
Wow, thank you! I understand it all now.- Dölj citerad text -

They helped mee too, just look at an earlier post where finally...
Hmm,,, played around... it cleared...

StringBuilder sb1 = new StringBuilder("Hello");
StringBuilder sb2 = new StringBuilder(" world");
sb1.Append(sb2);
Console.WriteLine(sb1); // Hello world
sb1 = sb2;
Console.WriteLine(sb1); // world


starting to get it... just took a while.. 8)


And then... it hit me...
and naturally

StringBuilder sb1 = new StringBuilder("Hello");
StringBuilder sb2 = new StringBuilder(" world");
sb1.Append(sb2);
Console.WriteLine(sb1); // Hello world
sb1 = sb2;
Console.WriteLine(sb1); // world
Console.WriteLine(sb2); // world


Just had C in my head...

//CY
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top