#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:

Advertisement

#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

#268 – You Must Set the Value of All out Parameters Before Returning from a Method

You can use out parameters as a way of returning multiple data values from a method to its caller.  Because the intention of an output parameter is to return data to the caller, you must assign some value to every parameter marked as out before you can return from a method.  The compiler will enforce this rule.

In the example below, we’ve failed to set a value for the barkPhrase output parameter.

        public void GetDogVitals(out string fullName, out int age, out string barkPhrase)
        {
            fullName = string.Format("{0}, {1}", Name, Title);
            age = Age;
            //barkPhrase = BarkPhrase;
        }

When we try to compile the code, we’ll get an error telling us that we must assign a value to the barkPhrase output parameter before control leaves the method.

#267 – Passing Data Back from a Method Using out Parameters

If you want a method to return a single value, you can return that value as the result of the method.

        public int AgeInHumanYears()
        {
            return Age * 7;
        }

However, there might be times when you want to return more than one data item from a method.  You can do this with out parameters.  Putting the keyword out in front of a parameter tells the compiler that the caller will not pass data in, but the method will pass data out.

        public void GetDogVitals(out string fullName, out int age, out string barkPhrase)
        {
            fullName = string.Format("{0}, {1}", Name, Title);
            age = Age;
            barkPhrase = BarkPhrase;
        }

When you call the method, you also need to use the out keyword on the variables passed into the method.

            string hisFullName;
            int hisAge;
            string hisBark;
            kirby.GetDogVitals(out hisFullName, out hisAge, out hisBark);