ref (C# リファレンス)

ref キーワードによって、値渡しではなく、参照渡しによって引数が渡されます。 参照渡しで渡すことにより、呼び出されたメソッドのパラメーターに対する変更が、呼び出し元のメソッドに反映されます。 たとえば、呼び出し元がローカル変数の式、または配列要素のアクセス式を渡し、呼び出されたメソッドが ref パラメーターが参照するオブジェクトを置き換える場合、呼び出し元のローカル変数または配列要素は新しいオブジェクトを参照します。

注意

参照渡しの概念と参照型の概念を混同しないでください。2 つの概念は同じではありません。メソッドのパラメーターは、値型か参照型かどうかに関係なく、ref によって変更できます。参照渡しで渡される場合、値型はボックス化されません。

ref パラメーターを使用するには、メソッド定義と呼び出し元のメソッドの両方が、次の例に示すように ref キーワードを明示的に使用する必要があります。

    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
        }
    }

ref パラメーターに渡す引数は、渡す前に初期化する必要があります。 これは、引数を渡す前に明示的に初期化する必要がある out パラメーターとは異なります。 詳細については、「out」を参照してください。

クラスのメンバーは、ref と out だけが異なるシグネチャを持つことはできません。 1 つの型の 2 つのメンバー間の違いが、1 つには ref パラメーターがあり、もう 1 つには out パラメーターがあることのみの場合は、コンパイラ エラーが発生します。 たとえば、次のコードはコンパイルされません。

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) { }
}

ただし、次の例に示すように、1 つのメソッドに ref または out パラメーターがあり、もう 1 つのメソッドに値パラメーターがある場合は、オーバーロードすることができます。

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

非表示やオーバーライドなど、シグネチャの一致が必要な他の状況では、ref と out はシグネチャの一部であり互いに一致しません。

プロパティは変数ではありません。 プロパティはメソッドであり、ref パラメーターに渡すことはできません。

配列を渡す方法については、「ref と out を使用した配列の引き渡し (C# プログラミング ガイド)」を参照してください。

次の種類のメソッドには、ref キーワードと out キーワードを使用することはできません。

  • async 修飾子を使用して定義した Async メソッド

  • yield return または yield break ステートメントを含む Iterator メソッド

使用例

前の例は、参照渡しで値型を渡したときの動作を示しています。 また、ref キーワードを使用して参照型を渡すこともできます。 参照型を参照渡しで渡すと、呼び出されたメソッドで、参照パラメーターが参照する呼び出し元のメソッドのオブジェクトを置換できます。 オブジェクトの格納場所は、参照パラメーターの値としてメソッドに渡されます。 パラメーターの格納場所の値を変更する場合は (新しいオブジェクトをポイント)、呼び出し元が参照する格納場所を変更することもできます。 次の例では、参照型のインスタンスを ref パラメーターとして渡します。 参照型を値渡しまたは参照渡しで渡す方法の詳細については、「参照型のパラメーターの引き渡し (C# プログラミング ガイド)」を参照してください。

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# 言語仕様

詳細については、「C# 言語仕様」を参照してください。言語仕様は、C# の構文と使用法に関する信頼性のある情報源です。

参照

関連項目

パラメーターの引き渡し (C# プログラミング ガイド)

メソッドのパラメーター (C# リファレンス)

C# のキーワード

概念

C# プログラミング ガイド

その他の技術情報

C# リファレンス