What is the difference between "ref" and "out" keywords?

The ref Modifier

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Hello World!");
        int id = 1;
        Console.WriteLine("id = " + id.ToString());  // id = 1
        string newString = GetString(ref id);
        Console.WriteLine("id = " + id.ToString());  // id = 2
    }

    public static string GetString(ref int id)
    {
        id += 1;
        return "String";
    }
}

The out Modifier

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Hello World!");
        int id =1;
        Console.WriteLine("id = " + id.ToString());  // id = 1
        string newString = GetString(out id);
        Console.WriteLine("id = " + id.ToString());  // id = 2
    }

    public static string GetString(out int id)
    {
        id = 2;
        return "String";
    }
}

Note: Both ref and out parameters are treated the same at compile-time but different at run-time.

ref out
The parameter or argument must be initialized first before it is passed to the ref Not required to initialize the parameter or argument before passing it to an out
Not required to assign or initialize the value of a parameter before returning to the calling method. A called method is required to assign or initialize a value of a parameter before returning to the calling method.
Data can be passed bi-directionally Data is passed only unidirectional way ( from the called method to the caller method)
Useful when the called method is also needed to modify the passed parameter Useful when multiple values need to be returned from a function or method.