To ref or not to ref

  • (3 Pages)
  • +
  • 1
  • 2
  • 3

34 Replies - 2925 Views - Last Post: 11 February 2011 - 03:11 PM

#1 raziel_  Icon User is offline

  • Like a lollipop
  • member icon

Reputation: 463
  • View blog
  • Posts: 4,255
  • Joined: 25-March 09

To ref or not to ref

Posted 10 February 2011 - 03:14 AM

Hi to everyone :)

I play the other day with some classes and i notice something:

    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }
        public void pp_txt(ref TextBox txtTest)
        {
            txtTest.Text = "Test";
        }
    }
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Form2 frm2 = new Form2();
            frm2.pp_txt(ref textBox1);
        }
    }



and this:

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Form2 frm2 = new Form2();
            frm2.pp_txt(textBox1);
        }
    }

    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }
        public void pp_txt(TextBox txtTest)
        {
            txtTest.Text = "Test";
        }
    }



It looks like because TextBox is a class and the operator "=" is changed in C# you can pass it without using the "ref" operator for classes(if i recall correct in C++ you can do this only with pointers) and in the two examples the text in textbox will change. So this is how this looks to me and when almost everything is class type in C# why should we use ref(that is not for variables). To be honest i dont remember a clear example where to use ref. So why should we use ref when we can pass the classes without the ref operator?

This post has been edited by NoBrain: 10 February 2011 - 03:19 AM


Is This A Good Question/Topic? 0
  • +

Replies To: To ref or not to ref

#2 CodeJunkie  Icon User is offline

  • New D.I.C Head

Reputation: 5
  • View blog
  • Posts: 21
  • Joined: 19-January 09

Re: To ref or not to ref

Posted 10 February 2011 - 04:24 AM

Well as far as i know in C# all parameters are passed by value, apart from arrays and complex data types.

When you pass an int for example to a method as a parameter, the method gets a copy of this variable, but when the variable is passed to a method by reference the method gets the actual variable.

class Program
{
    static void PassByValueMethod(int nValue)
    {
        // We now get a new copy of the variable. Altering this variable will not change the original variable passed in.
        nValue = 10;
    }

    static void PassByRefMethod(ref int nValue)
    {
        // We now get a reference to this variable. Altering this variable will change the original variable passed in.
        nValue = 20;
    }

    static void Main(string[] args)
    {
        int nValue = 0;

        // Display the value.
        Console.WriteLine("Value: {0}", nValue);

        // Pass by value.
        PassByValueMethod(nValue);
        Console.WriteLine("After pass by value: {0}", nValue);

        // Pass By reference.
        PassByRefMethod(ref nValue);
        Console.WriteLine("After pass by ref: {0}", nValue);

        // Hold the console open.
        Console.Read();
    }
}


Was This Post Helpful? 0
  • +
  • -

#3 raziel_  Icon User is offline

  • Like a lollipop
  • member icon

Reputation: 463
  • View blog
  • Posts: 4,255
  • Joined: 25-March 09

Re: To ref or not to ref

Posted 10 February 2011 - 05:03 AM

So as i say before i know that you should pass variable by ref as argument to a function so that you can change its value in that function. What i`m asking is there any need to pass class by ref to a function when even if you dont the changes that you make also change the class that you pass. as you see in my example in the both ways the text property in the textbox1 will be changed with some value. And as you see both ways will be correct and will not result any errors or warnings. The thing is that (the way i explain it) is because Microsoft change the operator "=" in C# its passing the classes by ref. on it self and i guess its useless to pass the class this way :frm2.pp_txt(ref textBox1); when it is the same as frm2.pp_txt(textBox1);. Am i correct or is there anyplace that you should use ref for passing anything else then variables.

EDIT: to be correct only variables types must be passed by ref. if you want to change their values in the function(as far as i see for now)

This post has been edited by NoBrain: 10 February 2011 - 05:08 AM

Was This Post Helpful? 0
  • +
  • -

#4 raziel_  Icon User is offline

  • Like a lollipop
  • member icon

Reputation: 463
  • View blog
  • Posts: 4,255
  • Joined: 25-March 09

Re: To ref or not to ref

Posted 10 February 2011 - 05:25 AM

Ok if this is the case about classes then why is this not working?:

        private void button1_Click(object sender, EventArgs e)
        {
            string strTest = "ABCD";
            blabla(strTest);

        }
        private void blabla(string strT)
        {
            strT = "DCBA";
        }


when public sealed class String lol???
Was This Post Helpful? 0
  • +
  • -

#5 Robin19  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 256
  • View blog
  • Posts: 529
  • Joined: 07-July 10

Re: To ref or not to ref

Posted 10 February 2011 - 05:39 AM

MSDN:
The following example demonstrates passing a reference-type parameter, myArray, by value, to a method, Change. Because the parameter is a reference to myArray, it is possible to change the values of the array elements. However, the attempt to reassign the parameter to a different memory location only works inside the method and does not affect the original variable, myArray.

So assigning the variable to a new value changes the memory location the local pointer is pointing to. The original pointer is still pointed to an unchanged memory location. IIRC, strings are objects but basically perform as a value type when passed. This is because most (all?) string functions return a new string value you have to assign as instead of changing the original string.

I think the point of using ref on objects is this: it is important to know that a function will attempt to change the object. Although you know objects can be changed when passed, I bet a lot of programmers don't think about it when coding. If you force them to use the ref keyword, you remind them that you will be messing with their object.

This post has been edited by Robin19: 10 February 2011 - 05:40 AM

Was This Post Helpful? 2
  • +
  • -

#6 eclipsed4utoo  Icon User is offline

  • Not Your Ordinary Programmer
  • member icon

Reputation: 1524
  • View blog
  • Posts: 5,957
  • Joined: 21-March 08

Re: To ref or not to ref

Posted 10 February 2011 - 06:53 AM

It really depends on the object that is being passed. Reference types will be passed by reference. Value types will be passed by value unless specified to pass by reference using the ref keyword.

Sample code...

class Program
{
    static void Main(string[] args)
    {
        // passing a value type by value
        int number = 1;
        ChangeNumber(number);
        Console.WriteLine("Main Method: Number = " + number);

        // passing a value type by reference
        int number2 = 4;
        ChangeNumber(ref number2);
        Console.WriteLine("Main Method: Ref Number = " + number2);

        // passing a reference type
        Person p = new Person();
        p.Name = "John Doe";
        ChangeAge(p);
        Console.WriteLine("Main Method: Age = " + p.Age);

        Console.Read();
    }

    private static void ChangeNumber(int num)
    {
        num = 8;
        Console.WriteLine("Change Number Method:  Number = " + num);
    }

    private static void ChangeNumber(ref int num)
    {
        num = 5;
        Console.WriteLine("Change Number Ref Method:  Number = " + num);
    }

    private static void ChangeAge(Person p)
    {
        p.Age = 24;

        Console.WriteLine("Change Age Method: Age = " + p.Age);
    }
}

public class Person
{
    public string Name;
    public int Age;

    public void SetData()
    {
        Name = "Test";
        Age = 31;
    }
}




Since Person is a reference type, it is passed by reference to the method without having to use the ref keyword. So when the method changes the object, the original object changes also. int is a value type and is passed as a value type unless specified to pass by reference. So in the first test, it's passed by value, so the original value doesn't change. The second test passes it by reference, so the original value does change.
Was This Post Helpful? 2
  • +
  • -

#7 raziel_  Icon User is offline

  • Like a lollipop
  • member icon

Reputation: 463
  • View blog
  • Posts: 4,255
  • Joined: 25-March 09

Re: To ref or not to ref

Posted 10 February 2011 - 07:25 AM

Ty both of you :)
so then how can i create new instance of a class that i use (i mean in the function to be new instance and it will not effect the class that i pass but have all the old values of the passed class)
Was This Post Helpful? 0
  • +
  • -

#8 eclipsed4utoo  Icon User is offline

  • Not Your Ordinary Programmer
  • member icon

Reputation: 1524
  • View blog
  • Posts: 5,957
  • Joined: 21-March 08

Re: To ref or not to ref

Posted 10 February 2011 - 07:31 AM

You could implement the IClonable interface in your class. That would let you clone it in the method.

http://msdn.microsof...icloneable.aspx

simple solution...

Person class
public class Person : ICloneable
{
    public string Name;
    public int Age;

    #region ICloneable Members

    public object Clone()
    {
        return this.MemberwiseClone();
    }

    #endregion
}



static void Main(string[] args)
{
    // passing a reference type
    Person p = new Person();
    p.Name = "John Doe";
    ChangeAge(p);
    Console.WriteLine("Main Method: Age = " + p.Age);

    Console.Read();
}

private static void ChangeAge(Person p)
{
    Person newPerson = (Person)p.Clone();
    newPerson.Age = 24;

    Console.WriteLine("Change Age Method: Name = " + newPerson.Name);
    Console.WriteLine("Change Age Method: Age = " + newPerson.Age);
}



You will see that inside the method, the newPerson object has the name of the original object, but when changing the age of the newPerson object, it doesn't change the original object.
Was This Post Helpful? 2
  • +
  • -

#9 Curtis Rutland  Icon User is online

  • (╯□)╯︵ (~ .o.)~
  • member icon


Reputation: 4311
  • View blog
  • Posts: 7,467
  • Joined: 08-June 10

Re: To ref or not to ref

Posted 10 February 2011 - 07:46 AM

You'll have to do what eclipsed said. Remember though, all classes (not structs) are stored by reference. The importance of this is, if you have a class that contains other classes, it's possible to clone the class, but not clone the child classes. Remember that classes are stored as pointers. So if you just copy the reference, then you have multiple things pointing at the same block of memory, and if "a" changes, "b" shows the same change.

The ref keyword is a very interesting beast. When you pass something with the ref keyword, you're actually passing a pointer. Since the class is already a reference type, you're passing a pointer to a pointer. The dereferencing is automatically handled for you, but the practical upshot of it is, you are allowed to reassign the variable.

It's not something you typically want to do without a good reason. More often than not, you can get away with using a return value.

This post has been edited by insertAlias: 10 February 2011 - 07:47 AM

Was This Post Helpful? 2
  • +
  • -

#10 raziel_  Icon User is offline

  • Like a lollipop
  • member icon

Reputation: 463
  • View blog
  • Posts: 4,255
  • Joined: 25-March 09

Re: To ref or not to ref

Posted 10 February 2011 - 07:56 AM

So if i understand correct its not recommended to pass classes by reference using ref keyword(to make pointer of an pointer)?

This post has been edited by NoBrain: 10 February 2011 - 07:58 AM

Was This Post Helpful? 0
  • +
  • -

#11 lordofduct  Icon User is online

  • I'm a cheeseburger
  • member icon


Reputation: 2506
  • View blog
  • Posts: 4,615
  • Joined: 24-September 10

Re: To ref or not to ref

Posted 10 February 2011 - 07:57 AM

to show an example of where you might use a ref to a class type to update the variable...

lets consider a pass/fail scenario that you want to return.

// reads a multi-value from the database as defined in 'param'
// and populates the ref'd array with the results as an array. 
// returns a boolean representing if the array was updated or not.
public bool ReadToArray(string param, ref string[] arr)
{
	string results = myDatabase.Read(param);
	
	if(!results.StartsWith("ERROR"))
	{
		arr = results.Split(Chr(254));
		return true;
	} else {
		return false;
	}
}




this is sort of similar to a few bits of code I actually use when communicating to the proprieatry database we use (no the SQL stuff in .Net does not work with it). The database returns a string of the multi-values that I'm reading for, but it returns a string starting with a unique string flagging that we failed, followed by a message for the failure.
Was This Post Helpful? 1
  • +
  • -

#12 raziel_  Icon User is offline

  • Like a lollipop
  • member icon

Reputation: 463
  • View blog
  • Posts: 4,255
  • Joined: 25-March 09

Re: To ref or not to ref

Posted 10 February 2011 - 08:04 AM

Ok but maybe i fail to understand where you pass an class by reference.
Edit: Oh sorry the array but will it not be the same as
public bool ReadToArray(string param, string[] arr)?

This post has been edited by NoBrain: 10 February 2011 - 08:05 AM

Was This Post Helpful? 0
  • +
  • -

#13 lordofduct  Icon User is online

  • I'm a cheeseburger
  • member icon


Reputation: 2506
  • View blog
  • Posts: 4,615
  • Joined: 24-September 10

Re: To ref or not to ref

Posted 10 February 2011 - 08:10 AM

it's not often (arrays are classes, or consider any type of collection... say I said I used IList or something instead).

but sometimes you might.

Usually it's when you can't return the result as the return value. Because maybe that return value is already something else (like in my example it's a boolean showing pass fail).

Another might be because you return multiple values. Let's show that same example again, with a minor tweak:

public bool ReadToArray(string param, ref string[] arr, ref string errormsg)
{
	string results = myDatabase.Read(param);
	
	if(!results.StartsWith("ERROR"))
	{
		arr = results.Split(Chr(254));
		return true;
	} else {
		errormsg = results.SubString(5);
		return false;
	}
}


Was This Post Helpful? 1
  • +
  • -

#14 raziel_  Icon User is offline

  • Like a lollipop
  • member icon

Reputation: 463
  • View blog
  • Posts: 4,255
  • Joined: 25-March 09

Re: To ref or not to ref

Posted 10 February 2011 - 08:17 AM

ty very much i try it (kinda) and it dose not populate the array if its not passed by ref
Was This Post Helpful? 0
  • +
  • -

#15 eclipsed4utoo  Icon User is offline

  • Not Your Ordinary Programmer
  • member icon

Reputation: 1524
  • View blog
  • Posts: 5,957
  • Joined: 21-March 08

Re: To ref or not to ref

Posted 10 February 2011 - 08:21 AM

EDITED: most of this post was wrong.
Was This Post Helpful? 0
  • +
  • -

  • (3 Pages)
  • +
  • 1
  • 2
  • 3