#674 – Can Overload If Parameters Differ Only by ref Modifier

You can overload methods, i.e. create two methods with the same name, if the methods have different parameter lists, where the lists differ in the number or type of the parameters.  For example:

        public void Fetch(Bone b)
        {
            Console.WriteLine(string.Format("Fetching bone {0}", b.Description));
        }

        public void Fetch(Dog d)
        {
            Console.WriteLine(string.Format("I'll go get {0}", d.Name));
        }

You can also overload methods if they differ only in their use of the ref modifier.  One method can accept a parameter passed by value and you can have another version of the method that allows passing the parameter by reference.

        public void Bark(string sound)
        {
            Console.WriteLine(sound);
        }

        public void Bark(ref string sound)
        {
            Console.WriteLine(sound);

            // Update caller's copy of sound variable
            sound = sound + "!";
        }
            Dog d = new Dog("Rex", 3);
            string sound = "woof";
            d.Bark(sound);
            d.Bark(ref sound);   // woof!
            d.Bark(ref sound);   // woof!!
Advertisement

#278 – Passing an Array by Reference

You can pass an array by reference to a method, using the ref or out parameter modifier, when you want the method to change the parameter to refer to a different array.

Here’s an example of a method that accepts an array and then overwrites the reference so that it points to a new array.

        public static void DoubleADogList(ref Dog[] list)
        {
            Dog[] bigList = new Dog[2 * list.Count()];

            int i2 = 0;
            foreach (Dog d in list)
            {
                bigList[i2++] = new Dog(d.Name, d.Age, d.Motto);
                bigList[i2++] = new Dog(d.Name + " Clone", d.Age, d.Motto);
            }

            // Change original reference to refer to new list
            list = bigList;
        }

We can call this method, passing it an array. When the method returns, the array variable points to the new (larger) array.

            Dog d1 = new Dog("Kirby", 13, "Chase balls");
            Dog d2 = new Dog("Jack", 17, "Bark");

            Dog[] list = new Dog[] { d1, d2 };

            Dog.DoubleADogList(ref list);

 

#276 – Passing a struct by Reference

You can pass a struct by reference using the ref or out parameter modifiers.  Use ref when you want a method to read and write to the struct.  Use out for a struct that is meant to be an output parameter.

Assuming that you’ve defined the following struct:

    public struct MovieInfo
    {
        public string Title;
        public int Year;
        public string Director;
    }

You might pass an instance of MovieInfo by reference like this:

        public static void DisplayThenUpper(ref MovieInfo minfo)
        {
            Console.WriteLine("{0} ({1}), {2}", minfo.Title, minfo.Year, minfo.Director);

            minfo.Title = minfo.Title.ToUpper();
            minfo.Director = minfo.Director.ToUpper();
        }

After we call the method, the contents of the struct have been modified.

            MovieInfo minf = new MovieInfo();
            minf.Title = "Citizen Kane";
            minf.Year = 1941;
            minf.Director = "Orson Welles";

            Movie.DisplayThenUpper(ref minf);

            Console.WriteLine("{0}, {1}", minf.Title, minf.Director);

Output after the program has finished:

#273 – Parameter Modifier Summary

Here’s a summary of the different parameter modifiers and how the behavior changes for each, when using them with value-typed and reference-typed variables.

  • No modifier – value types
    • Copy of value passed to method
    • Method can read value
  • No modifier – reference types
    • Reference to object passed to method
    • Method can read/write object contents
  • ref modifier – value types
    • Reference to variable passed to method
    • Method can read/write variable
  • ref modifier – reference types
    • Reference to object reference passed to method
    • Method can read/write object contents
    • Method can change reference to point to new object
  • out modifier – value types
    • Reference to variable passed to method
    • Method must write new value to variable
  • out modifier – reference types
    • Reference to object reference passed to method
    • Method must change reference to point to new object

#272 – Differences Between ref and out Parameters

Ref and out parameters in C# are implemented in the same way, in the compiled code.  In both cases, a parameter is passed by reference, giving the method called a chance to change the underlying value.

ref and out parameters different purposes:

  • ref parameters are for input/output – a value is passed into a method and a new value is passed out
  • out parameters are for output – a value is passed out of a method

The compiler enforces the following rules:

  • ref parameters
    • A value must be assigned to parameter before method is called
    • Parameter may be referenced inside method before being written to
    • Parameter may be written to before returning from method
  • out parameters
    • A value may be assigned before method is called (but cannot be used inside method)
    • Parameter may not be referenced inside method before being written to
    • Parameter must be written to before returning from method

#270 – Passing a Reference Type by Reference

When you pass a reference type by value to a method, you pass in a reference to the object.  The method can change the object, but can’t change the reference.

        public static void AnnotateMotto(Dog d)
        {
            // Change the dog's motto
            d.Motto = d.Motto + " while panting";
        }

You can also pass a reference type by reference, which means that the method can change not only the contents of the object pointed to, but change the reference, causing it to refer to a different object.

        public static void FindNewFavorite(ref Dog fav)
        {
            fav.Motto = "No longer the favorite";

            foreach (Dog d in AllDogs)
            {
                if (d.Motto.Contains("ball"))
                    fav = d;
            }
        }

Below is an example of calling this method.

            Dog kirby = new Dog("Kirby");
            kirby.Motto = "Retrieve balls";

            Dog jack = new Dog("Jack");
            jack.Motto = "Growl at people";

            Dog myFav = jack;
            Dog.FindNewFavorite(ref myFav);

            Console.WriteLine(myFav.Name);   // Kirby