Class passing, to ref or not to ref...

I

itarizin

Today I found as ignorance owe me..
Let me explain what I'm tring to do and fail (fail: in my needs)

For example, I've my stupid class:

public class Hello
{
private int x = 0;

public Hello()
{ }

public int Ics
{
get { return this.x; }
set { this.x = value; }
}
}

Perfect, now suppose, to call from a form another form and give its an
instance of our Hello class:

Hello m_hello = new Hello();
m_hello.Ics = 5;

MyForm m_frm = new MyForm();
// Assume that Data is a MyForm property type object
m_frm.Data = m_hello;
m_frm.ShowDialog(this);

Great, now from the other side, I mean the open MyForm, at OnLoad I'll
do a cast from Data to Hello than I'll modify Ics property and will
close the form WITHOUT any reassignment of Data (HIT!).

// On Load
Hello m_frmhello = (Hello)this.Data;
m_frmhello.Ics = 10;
this.Close();

On back to main form, the Hello instance (m_hello) will have the new
Ics value!! I mean will be "10".
That looks like a ref pass to Data, when it's the last thing I want.
Instead, passing to Data an object kinda int, string, bool... or a
struct, this pass will be NOT by reference. This means that Ics will
be however "5".

Can anyone can explain me why? It's cause heap and stack ? There's a
way to avoid this behave without cloning my Hello instance at the
passing moment?




Thanks one billion or maybe more ;)
 
J

Jon Skeet [C# MVP]

G

Gamon02

Seehttp://pobox.com/~skeet/csharp/parameters.html
andhttp://pobox.com/~skeet/csharp/memory.html

In addition, a "beta quality" article may be of some use - it's going
through a bit of peer review at the moment, and isn't finished, but you
may find it useful:

http://pobox.com/~skeet/csharp/references.html
<snip>

Thanks, I found first URL just few seconds ago ;)
Now start to learn...and crossing fingers resolve my problem.
Thanks
 
B

Bruce Wood

<snip>

Thanks, I found first URL just few seconds ago ;)
Now start to learn...and crossing fingers resolve my problem.
Thanks

I should also point out that if you search the archives of this
newsgroup, you will find many, many threads on reference types versus
value types, and pass by reference, cloning, etc.

And to answer the last question in your original post, the usual way
to solve this problem is to clone (copy) the object when you make the
method call, and pass the copy.
 
J

Jon Skeet [C# MVP]

And to answer the last question in your original post, the usual way
to solve this problem is to clone (copy) the object when you make the
method call, and pass the copy.

Or to make the class act like String - make it immutable, with methods
which don't change the state of the existing instance, but which return
a new instance with changes.
 
G

Gamon02

Yes, is what I thought to do, but same classes are so annoying to
implement IClonable (looooong deep clone)
Or to make the class act like String - make it immutable, with methods
which don't change the state of the existing instance, but which return
a new instance with changes.


What exactly you mean for "act like String" ? How can a class do that?
Inherit to String class?
 
D

Dave Sexton

Hi,
What exactly you mean for "act like String" ? How can a class do that?
Inherit to String class?

You can overload the implicit cast operator:

class MyString
{
public string Value { get { return value; } }
private readonly string value;

public MyString(string value)
{
if (value == null)
throw new ArgumentNullException("value");

this.value = value;
}

public override int GetHashCode()
{
return value.GetHashCode();
}

public override bool Equals(object obj)
{
return value.Equals(obj);
}

public override string ToString()
{
return value;
}

public static implicit operator string(MyString myString)
{
return myString.Value;
}

public static implicit operator MyString(string str)
{
return (str == null) ? null : new MyString(str);
}
}

static void Main()
{
MyString hello = "Hello ";
string world = new MyString("World!");

Console.WriteLine("{0}{1}", hello, world);

MyString nullRef = (string) null;
Console.WriteLine(nullRef == null);
}

If you want the same properties and methods you'll have to implement them,
one by one.
 
D

Dave Sexton

Hi,
public static implicit operator string(MyString myString)
{
return myString.Value;
}

Probably should check for null here too :)

public static implicit operator string(MyString myString)
{
return (myString == null) ? null : myString.Value;
}
 
J

Jon Skeet [C# MVP]

What exactly you mean for "act like String" ? How can a class do that?
Inherit to String class?

No - I only meant in terms of immutability. String is the usual
example given for an immutable class, that's all. Once you've created
a string, you can't change it. The methods which sounds like they
change it return a new one. You can implement the same kind of
behaviour yourself.

Jon
 
?

=?ISO-8859-1?Q?G=F6ran_Andersson?=

Today I found as ignorance owe me..
Let me explain what I'm tring to do and fail (fail: in my needs)

For example, I've my stupid class:

public class Hello
{
private int x = 0;

public Hello()
{ }

public int Ics
{
get { return this.x; }
set { this.x = value; }
}
}

Perfect, now suppose, to call from a form another form and give its an
instance of our Hello class:

Hello m_hello = new Hello();
m_hello.Ics = 5;

MyForm m_frm = new MyForm();
// Assume that Data is a MyForm property type object
m_frm.Data = m_hello;
m_frm.ShowDialog(this);

Great, now from the other side, I mean the open MyForm, at OnLoad I'll
do a cast from Data to Hello than I'll modify Ics property and will
close the form WITHOUT any reassignment of Data (HIT!).

// On Load
Hello m_frmhello = (Hello)this.Data;
m_frmhello.Ics = 10;
this.Close();

On back to main form, the Hello instance (m_hello) will have the new
Ics value!! I mean will be "10".
That looks like a ref pass to Data, when it's the last thing I want.
Instead, passing to Data an object kinda int, string, bool... or a
struct, this pass will be NOT by reference. This means that Ics will
be however "5".

Can anyone can explain me why?

The variable m_hello contains a reference to the object you created.
What you put in the Data property is a copy of the value of the
variable. As the variable is a reference, you get a copy the reference.
It's cause heap and stack ?
Nope.

There's a
way to avoid this behave without cloning my Hello instance at the
passing moment?

Well, you don't neccesarily have to clone the instance at that precise
moment, but there is no automatic cloning of objects. If you want
another copy of your object, you have to create a copy of it.
 

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

Top