Share via


ref (Referência de C#)

A palavra-chave ref faz com que um argumento seja passado por referência, não por valor. O efeito de passar por referência é que qualquer alteração no parâmetro do método chamado será refletida no método chamado. Por exemplo, se o chamador passa uma expressão variável local ou uma expressão de acesso do elemento de matriz e o método chamado substituir o objeto ao qual o parâmetro ref se refere, então a variável local do chamador ou o elemento da matriz fará agora referência ao novo objeto.

Dica

Não confunda o conceito de passar por referência com o conceito de tipos de referência.Os dois conceitos não são iguais.Um parâmetro de método pode ser modificado por ref, independentemente de ele ser um tipo de valor ou um tipo de referência.Não há nenhuma conversão boxing de um tipo de valor quando ele é passado por referência.

Para usar um parâmetro ref, a definição do método e o método de chamada devem usar explicitamente a palavra-chave ref, como mostrado no exemplo a seguir.

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

Um argumento que é passado para um parâmetro ref deve ser inicializado antes de ser passado. Isso é diferente dos parâmetros out, cujos argumentos não precisam ser inicializados explicitamente antes de serem passados. Para obter mais informações, consulte out.

Os membros de uma classe não podem ter assinaturas que diferem somente por ref e out. Ocorrerá um erro de compilador se a única diferença entre os dois membros de um tipo for que um deles possui um parâmetro ref e o outro possui um parâmetro out. O código a seguir, por exemplo, não é compilado.

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

No entanto, pode haver sobrecarga quando um método tiver um parâmetro ref ou out e o outro tiver um parâmetro de valor, como mostrado no exemplo a seguir.

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

Em outras situações que exigem correspondência de assinatura, como ocultar ou substituir, ref e out fazem parte da assinatura e não são correspondentes.

Propriedades não são variáveis. Elas são métodos e não podem ser passadas para parâmetros ref.

Para obter informações sobre como passar matrizes, consulte Passando matrizes com o uso de ref e out (Guia de Programação em C#).

Não é possível usar as palavras-chave ref e out para os seguintes tipos de métodos:

  • Métodos assíncronos, que você define usando o modificador async.

  • Métodos de iterador, que incluem uma instrução yield return ou yield break.

Exemplo

Os exemplos anteriores demonstram o que acontece quando você passa tipos de valor por referência. Também é possível usar a palavra-chave ref para passar tipos de referência. Passar um tipo de referência por referência permite que o método chamado substitua o objeto no método de chamada ao qual se refere o parâmetro de referência. O local de armazenamento do objeto é passado para o método como o valor do parâmetro de referência. Se você alterar o valor no local de armazenamento do parâmetro (para apontar para um novo objeto), irá alterar também o local de armazenamento ao qual se refere o chamador. O exemplo a seguir passa uma instância de um tipo de referência como um parâmetro ref. Para obter mais informações sobre como passar tipos de referência por valor e por referência, consulte Passando parâmetros de tipo de referência (Guia de Programação em 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

Especificação da Linguagem C#

Para obter mais informações, consulte a Especificação da linguagem C#. A especificação da linguagem é a fonte definitiva para a sintaxe e o uso de C#.

Consulte também

Referência

Passando parâmetros (Guia de Programação em C#)

Parâmetros de método (Referência de C#)

Palavras-chave C#

Conceitos

Guia de Programação em C#

Outros recursos

Referência de C#