Definite Assignment

In c#, the compiler enforces a rule called definite assignment. This rule ensures that every local variable has been initialized before use. That is, the variable has a value before it's read from. This is in stark contrast to c++ where it is possible to read uninitialized variables.

Ref and Out Keywords

Like C++, c# only allows a single return value from any given method. Hence developers often define local variables in the method signature to be used purely as output variables. (Many OOD purists would argue that this breaks encapsulation.) This is the only case where the definite assignment rule works against you. You don't want to be forced to define these variables with dummy initial values that are ultimately overwritten by the method so C# allows you to add in the "out" keyword specifically in this case. When "out" is used the arguments are passed by reference. They need not be initialized before being passed to the method but the method is required to assign a value to them before it returns thus satisfying the definite assignment rule. The "ref" keyword, on the other hand, requires the variables to be definitely assigned before calling the method. The example below shows these behaviours:

    public class SomeOtherClass
    {
        public static void Main()
        {
            // unassigned local variables
            int a;
            int b;
            int c;

            SomeOtherClass.FetchValues(out a, out b, out c);
            // values of a,b,c have been initialised
            Console.WriteLine(String.Format("a={0} b={1} c={2}", a, b, c));

            SomeOtherClass.RotateValues(a, b, c);
            // values of a,b,c are unchanged
            Console.WriteLine(String.Format("a={0} b={1} c={2}",a,b,c));

            SomeOtherClass.RotateValues2(ref a, ref b, ref c);
            // values of a,b,c, have been rotated
            Console.WriteLine(String.Format("a={0} b={1} c={2}", a, b, c));
        }

        public static void FetchValues(out int a, out int b, out int c)
        {
            a = 1;
            b = 5;
            c = 16;
        }

        public static void RotateValues(int arg1, int arg2, int arg3)
        {
            int tmp = arg1;

            arg1 = arg2;
            arg2 = arg3;
            arg3 = tmp;
        }

        public static void RotateValues2(ref int a1, ref int a2, ref int a3)
        {
            int tmp = a1;

            a1 = a2;
            a2 = a3;
            a3 = tmp;
        }
    }

Note that:

  1. you cannot overload methods by simply changing the ref/out keywords.
  2. the ref/out keywords must be used in both the calling method and called method declaration.

Global Variables

Unlike C++, C# does not have global variables. If you wish to emulate them you can add a public static variable to a class.