Modificador de parâmetro in (referência do C#)in parameter modifier (C# Reference)

A palavra-chave in faz com que os argumentos sejam passados por referência.The in keyword causes arguments to be passed by reference. Ela torna o parâmetro formal um alias para o argumento, que deve ser uma variável.It makes the formal parameter an alias for the argument, which must be a variable. Em outras palavras, qualquer operação no parâmetro é feita no argumento.In other words, any operation on the parameter is made on the argument. É como as palavras-chave ref ou out, exceto que os argumentos in não podem ser modificados pelo método chamado.It is like the ref or out keywords, except that in arguments cannot be modified by the called method. Enquanto os argumentos ref podem ser modificados, os argumentos out devem ser modificados pelo método chamado, e essas modificações podem ser observadas no contexto da chamada.Whereas ref arguments may be modified, out arguments must be modified by the called method, and those modifications are observable in the calling context.

int readonlyArgument = 44;
InArgExample(readonlyArgument);
Console.WriteLine(readonlyArgument);     // value is still 44

void InArgExample(in int number)
{
    // Uncomment the following line to see error CS8331
    //number = 19;
}

O exemplo anterior demonstra que o modificador in é geralmente desnecessário no site de chamada.The preceding example demonstrates that the in modifier is usually unnecessary at the call site. Ele apenas é necessário na declaração do método.It is only required in the method declaration.

Observação

A palavra-chave in também pode ser usada com um parâmetro de tipo genérico para especificar que o parâmetro de tipo é contravariante, como parte de uma instrução foreach ou como parte de uma cláusula join em uma consulta LINQ.The in keyword can also be used with a generic type parameter to specify that the type parameter is contravariant, as part of a foreach statement, or as part of a join clause in a LINQ query. Para obter mais informações sobre o uso da palavra-chave in nesses contextos, confira in que fornece links para todos esses usos.For more information on the use of the in keyword in these contexts, see in, which provides links to all those uses.

As variáveis passadas como argumentos in precisam ser inicializadas antes de serem passadas em uma chamada de método.Variables passed as in arguments must be initialized before being passed in a method call. No entanto, o método chamado não pode atribuir um valor nem modificar o argumento.However, the called method may not assign a value or modify the argument.

O modificador de parâmetro in está disponível no C# 7.2 e posteriores.The in parameter modifier is available in C# 7.2 and later. As versões anteriores geravam o erro de compilador CS8107 ("o recurso 'referências somente leitura' não está disponível no C# 7.0.Previous versions generate compiler error CS8107 ("Feature 'readonly references' is not available in C# 7.0. Use a linguagem na versão 7.2 ou posteriores"). Confira como configurar a versão de linguagem do compilador em Selecionar a versão da linguagem C#.Please use language version 7.2 or greater.") To configure the compiler language version, see Select the C# language version.

As palavras-chave in, ref e out não são consideradas parte da assinatura do método para fins de resolução de sobrecarga.The in, ref, and out keywords are not considered part of the method signature for the purpose of overload resolution. Portanto, os métodos não poderão ser sobrecarregados se a única diferença for que um método usa um argumento ref ou in e o outro usa um argumento out.Therefore, methods cannot be overloaded if the only difference is that one method takes a ref or in argument and the other takes an out argument. Por exemplo, o código a seguir, não será compilado:The following code, for example, will not compile:

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

A sobrecarga com base na presença de in é permitida:Overloading based on the presence of in is allowed:

class InOverloads
{
    public void SampleMethod(in int i) { }
    public void SampleMethod(int i) { }
}

Regras de resolução de sobrecargaOverload resolution rules

Você pode entender as regras de resolução de sobrecarga para métodos por valor versus argumentos in, compreendendo a motivação dos argumentos in.You can understand the overload resolution rules for methods with by value vs. in arguments by understanding the motivation for in arguments. A definição de métodos usando parâmetros in é uma possível otimização de desempenho.Defining methods using in parameters is a potential performance optimization. Alguns argumentos de tipo struct podem ser grandes em tamanho e, quando os métodos são chamados em loops rígidos ou caminhos de código críticos, o custo da cópia dessas estruturas é crítico.Some struct type arguments may be large in size, and when methods are called in tight loops or critical code paths, the cost of copying those structures is critical. Os métodos declaram parâmetros in para especificar que argumentos podem ser passados por referência com segurança porque o método chamado não modifica o estado desse argumento.Methods declare in parameters to specify that arguments may be passed by reference safely because the called method does not modify the state of that argument. A passagem desses argumentos por referência evita a cópia (possivelmente) dispendiosa.Passing those arguments by reference avoids the (potentially) expensive copy.

A especificação de in em argumentos no site de chamada é normalmente opcional.Specifying in for arguments at the call site is typically optional. Não há diferença semântica entre passar argumentos por valor e transmiti-los por meio de referência usando o modificador in.There is no semantic difference between passing arguments by value and passing them by reference using the in modifier. O modificador in no site de chamada é opcional, pois não é necessário indicar que o valor do argumento pode ser alterado.The in modifier at the call site is optional because you don't need to indicate that the argument's value might be changed. Você adiciona explicitamente o modificador in no site de chamada para garantir que o argumento seja passado por referência, e não por valor.You explicitly add the in modifier at the call site to ensure the argument is passed by reference, not by value. O uso explícito de in tem dois efeitos:Explicitly using in has the following two effects:

Primeiro: especificar in no site de chamada força o compilador a selecionar um método definido com um parâmetro in correspondente.First, specifying in at the call site forces the compiler to select a method defined with a matching in parameter. Caso contrário, quando dois métodos diferem apenas na presença de in, a sobrecarga por valor é uma correspondência melhor.Otherwise, when two methods differ only in the presence of in, the by value overload is a better match.

Segundo: especificar in declara sua intenção de passar um argumento por referência.Second, specifying in declares your intent to pass an argument by reference. O argumento usado com in deve representar um local ao qual se possa fazer referência diretamente.The argument used with in must represent a location that can be directly referred to. As mesmas regras gerais para argumentos out e ref se aplicam: você não pode usar constantes, propriedades comuns ou outras expressões que produzem valores.The same general rules for out and ref arguments apply: You cannot use constants, ordinary properties, or other expressions that produce values. Caso contrário, a omissão de in no site de chamada informa ao compilador que você permitirá a criação de uma variável temporária para passar por referência de somente leitura para o método.Otherwise, omitting in at the call site informs the compiler that you will allow it to create a temporary variable to pass by read-only reference to the method. O compilador cria uma variável temporária para superar várias restrições com argumentos in:The compiler creates a temporary variable to overcome several restrictions with in arguments:

  • Uma variável temporária permite constantes de tempo de compilação como parâmetros in.A temporary variable allows compile-time constants as in parameters.
  • Uma variável temporária permite propriedades ou outras expressões para parâmetros in.A temporary variable allows properties, or other expressions for in parameters.
  • Uma variável temporária permite argumentos em que há uma conversão implícita do tipo de argumento para o tipo de parâmetro.A temporary variable allows arguments where there is an implicit conversion from the argument type to the parameter type.

Em todas as instâncias anteriores, o compilador cria uma variável temporária que armazena o valor da constante, da propriedade ou de outra expressão.In all the preceding instances, the compiler creates a temporary variable that stores the value of the constant, property, or other expression.

O código a seguir ilustra essas regras:The following code illustrates these rules:

static void Method(in int argument)
{
    // implementation removed
}

Method(5); // OK, temporary variable created.
Method(5L); // CS1503: no implicit conversion from long to int
short s = 0;
Method(s); // OK, temporary int created with the value 0
Method(in s); // CS1503: cannot convert from in short to in int
int i = 42;
Method(i); // passed by readonly reference
Method(in i); // passed by readonly reference, explicitly using `in`

Agora, vamos supor que outro método usando argumentos por valor estivesse disponível.Now, suppose another method using by value arguments was available. Os resultados são alterados conforme mostrado no código a seguir:The results change as shown in the following code:

static void Method(int argument)
{
    // implementation removed
}

static void Method(in int argument)
{
    // implementation removed
}

Method(5); // Calls overload passed by value
Method(5L); // CS1503: no implicit conversion from long to int
short s = 0;
Method(s); // Calls overload passed by value.
Method(in s); // CS1503: cannot convert from in short to in int
int i = 42;
Method(i); // Calls overload passed by value
Method(in i); // passed by readonly reference, explicitly using `in`

A única chamada de método em que o argumento é passado por referência é a chamada final.The only method call where the argument is passed by reference is the final one.

Observação

O código anterior usa int como o tipo de argumento por questão de simplicidade.The preceding code uses int as the argument type for simplicity. Como int não é maior que uma referência na maioria dos computadores modernos, não há nenhum benefício em passar um único int como uma referência readonly.Because int is no larger than a reference in most modern machines, there is no benefit to passing a single int as a readonly reference.

Limitações em parâmetros inLimitations on in parameters

Não é possível usar as palavras-chave in, ref e out para os seguintes tipos de métodos:You can't use the in, ref, and out keywords for the following kinds of methods:

  • Métodos assíncronos, que você define usando o modificador async.Async methods, which you define by using the async modifier.
  • Métodos de iterador, que incluem uma instrução yield return ou yield break.Iterator methods, which include a yield return or yield break statement.

Especificação da Linguagem C#C# Language Specification

Para obter mais informações, consulte a Especificação da linguagem C#.For more information, see the C# Language Specification. A especificação da linguagem é a fonte definitiva para a sintaxe e o uso de C#.The language specification is the definitive source for C# syntax and usage.

Consulte tambémSee also