Friday, August 13, 2010

ref (C# Reference)

ref (C# Reference)

The ref keyword causes arguments to be passed by reference. The effect is that any changes to the parameter in the method will be reflected in that variable when control passes back to the calling method.
NoteNote
Do not confuse the concept of passing by reference with the concept of reference types.
The two concepts are not the same.
A method parameter can be modified by ref regardless of whether it is a value type or
a reference type. There is no boxing of a value type when it is passed by reference.
To use a ref parameter, both the method definition and the calling method must explicitly use the ref keyword. For example:

class RefExample
    {
        static void Method(ref int i)
        {
            // Rest the mouse pointer over i to verify that it is an int.
            // The following statement would cause a compiler error if i
            // were boxed as an object.
            i = i + 44;
        }

        static void Main()
        {
            int val = 1;
            Method(ref val);
            Console.WriteLine(val);

            // Output: 45
        }
    }



An argument passed to a ref parameter must first be initialized. This differs from out, whose arguments do not have to be explicitly initialized before they are passed. For more information, see out.
Although the ref and out keywords cause different run-time behavior, they are not considered part of the method signature at compile time. Therefore, methods cannot be overloaded if the only difference is that one method takes a refargument and the other takes an out argument. The following code, for example, will not compile:

class CS0663_Example
{
    // Compiler error CS0663: "Cannot define overloaded 
    // methods that differ only on ref and out".
    public void SampleMethod(out int i) { }
    public void SampleMethod(ref int i) { }
}


Overloading can be done, however, if one method takes a ref or out argument and the other uses neither as in the following example:

class RefOverloadExample
    {
        public void SampleMethod(int i) { }
        public void SampleMethod(ref int i) { }
    }



Properties are not variables. They are actually methods, and therefore cannot be passed as ref parameters.
For information about how to pass arrays, see Passing Arrays Using ref and out (C# Programming Guide).
Example


Passing value types by reference, as demonstrated earlier in this topic, is useful, but ref is also useful for passing reference types. This allows called methods to modify the object to which the reference refers because the reference itself is being passed by reference. The following sample shows that when a reference type is passed as a ref parameter, the object itself can be changed. For more information, see Passing Reference-Type Parameters (C# Programming Guide).

class RefExample2
{
    static void Method(ref string s)
    {
        s = "changed";
    }
    static void Main()
    {
        string str = "original";
        Method(ref str);
        Console.WriteLine(str);
    }
}
// Output: changed


out parameter modifier

out parameter modifier (C# Reference)

The out keyword causes arguments to be passed by reference. This is like the ref keyword, except that ref requires that the variable be initialized before it is passed. To use an out parameter, both the method definition and the calling method must explicitly use the out keyword. For example:
class OutExample
{
    static void Method(out int i)
    {
        i = 44;
    }
    static void Main()
    {
        int value;
        Method(out value);
        // value is now 44
    }
}


Although variables passed as out arguments do not have to be initialized before being passed, the called method is required to assign a value before the method returns.
Although the ref and out keywords cause different run-time behavior, they are not considered part of the method signature at compile time. Therefore, methods cannot be overloaded if the only difference is that one method takes a refargument and the other takes an out argument. The following code, for example, will not compile:
class CS0663_Example
{
    // Compiler error CS0663: "Cannot define overloaded 
    // methods that differ only on ref and out".
    public void SampleMethod(out int i) { }
    public void SampleMethod(ref int i) { }
}


Overloading can be done, however, if one method takes a ref or out argument and the other uses neither, like this:
class OutOverloadExample
{
    public void SampleMethod(int i) { }
    public void SampleMethod(out int i) { i = 5; }
}


Properties are not variables and therefore cannot be passed as out parameters.
For information about passing arrays, see Passing Arrays Using ref and out (C# Programming Guide).
Example

Declaring an out method is useful when you want a method to return multiple values. The following example uses out to return three variables with a single method call. Note that the third argument is assigned to null. This enables methods to return values optionally.
class OutReturnExample
    {
        static void Method(out int i, out string s1, out string s2)
        {
            i = 44;
            s1 = "I've been returned";
            s2 = null;
        }
        static void Main()
        {
            int value;
            string str1, str2;
            Method(out value, out str1, out str2);
            // value is now 44
            // str1 is now "I've been returned"
            // str2 is (still) null;
        }
    }



out (Generic Modifier) (C# Reference)

Visual Studio 2010 - Visual C#
out (Generic Modifier) (C# Reference)

For generic type parameters, the out keyword specifies that the type parameter is covariant. You can use the out keyword in generic interfaces and delegates.
Covariance enables you to use a more derived type than that specified by the generic parameter. This allows for implicit conversion of classes that implement variant interfaces and implicit conversion of delegate types. Covariance and contravariance are supported for reference types, but they are not supported for value types.
An interface that has a covariant type parameter enables its methods to return more derived types than those specified by the type parameter. For example, because in .NET Framework 4, in IEnumerable<T>, type T is covariant, you can assign an object of the IEnumerabe(Of String) type to an object of the IEnumerable(Of Object) type without using any special conversion methods.
A covariant delegate can be assigned another delegate of the same type, but with a more derived generic type parameter.
For more information, see Covariance and Contravariance (C# and Visual Basic).
Example

The following example shows how to declare, extend, and implement a covariant generic interface. It also shows how to use implicit conversion for classes that implement a covariant interface.
// Covariant interface.
interface ICovariant<out R> { }

// Extending covariant interface.
interface IExtCovariant<out R> : ICovariant { }

// Implementing covariant interface.
class Sample : ICovariant { }

class Program
{
    static void Test()
    {
        ICovariant iobj = new Sample();         ICovariant istr = new Sample();          // You can assign istr to iobj because         // the ICovariant interface is covariant.         iobj = istr;     } }   
In a generic interface, a type parameter can be declared covariant if it satisfies the following conditions:
  • The type parameter is used only as a return type of interface methods and not used as a type of method arguments.
    NoteNote
    There is one exception to this rule. If in a covariant interface you have a contravariant
     generic delegate as a method parameter, you can use the covariant type as a generic 
    type parameter for this delegate. For more information about covariant and contravariant 
  • The type parameter is not used as a generic constraint for the interface methods.
The following example shows how to declare, instantiate, and invoke a covariant generic delegate. It also shows how to implicitly convert delegate types.
// Covariant delegate.
public delegate R DCovariant<out R>();

// Methods that match the delegate signature.
public static Control SampleControl()
{ return new Control(); }

public static Button SampleButton()
{ return new Button(); }

public void Test()
{            
    // Instantiate the delegates with the methods.
    DCovariant dControl = SampleControl;
    DCovariant
In a generic delegate, a type can be declared covariant if it is used only as a method return type and not used for method arguments.