Поделиться через


ref (C# Reference)

The ref keyword causes an argument to be passed by reference, not by value. The effect of passing by reference is that any change to the parameter in the method is reflected in the underlying argument variable in the calling method. The value of a reference parameter is always the same as the value of the underlying argument variable.

Note

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, as shown in the following 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 that is passed to a ref parameter must be initialized before it is passed. This differs from out parameters, whose arguments do not have to be explicitly initialized before they are passed. For more information, see out.

Members of a class can't have signatures that differ only by ref and out. A compiler error occurs if the only difference between two members of a type is that one of them has a ref parameter and the other has an out parameter. The following code, for example, doesn't 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) { }
}

However, overloading can be done when one method has a ref or out parameter and the other has a value parameter, as shown in the following example.

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

In other situations that require signature matching, such as hiding or overriding, ref and out are part of the signature and don't match each other.

Properties are not variables. They are methods, and cannot be passed to ref parameters.

For information about how to pass arrays, see Passing Arrays Using ref and out (C# Programming Guide).

Example

The previous examples demonstrate what happens when you pass value types by reference. You can also use the ref keyword to pass reference types. Passing a reference type by reference enables the called method to modify the object to which the reference parameter refers. The storage location of the object is passed to the method as the value of the reference parameter. If you change the storage location of the parameter, you change the storage location of the underlying argument. The following example passes an instance of a reference type as a ref parameter. For more information about how to pass reference types by value and by reference, see Passing Reference-Type Parameters (C# Programming Guide).

class RefExample2
{
    static void ChangeByReference(ref Product itemRef)
    {
        // The following line changes the address that is stored in  
        // parameter itemRef. Because itemRef is a ref parameter, the
        // address that is stored in variable item in Main also is changed.
        itemRef = new Product("Stapler", 99999);

        // You can change the value of one of the properties of
        // itemRef. The change happens to item in Main as well.
        itemRef.ItemID = 12345;
    }

    static void Main()
    {
        // Declare an instance of Product and display its initial values.
        Product item = new Product("Fasteners", 54321);
        System.Console.WriteLine("Original values in Main.  Name: {0}, ID: {1}\n",
            item.ItemName, item.ItemID);

        // Send item to ChangeByReference as a ref argument.
        ChangeByReference(ref item);
        System.Console.WriteLine("Back in Main.  Name: {0}, ID: {1}\n",
            item.ItemName, item.ItemID);
    }
}

class Product
{
    public Product(string name, int newID)
    {
        ItemName = name;
        ItemID = newID;
    }

    public string ItemName { get; set; }
    public int ItemID { get; set; }
}

// Output: 
//Original values in Main.  Name: Fasteners, ID: 54321

//Back in Main.  Name: Stapler, ID: 12345

C# Language Specification

For more information, see the C# Language Specification. The language specification is the definitive source for C# syntax and usage.

See Also

Reference

Passing Parameters (C# Programming Guide)

Method Parameters (C# Reference)

C# Keywords

Concepts

C# Programming Guide

Other Resources

C# Reference

Change History

Date

History

Reason

August 2012

Clarified the relationship between ref and out in overloading and overriding.

Content bug fix.