Modificador del parámetro in (referencia de C#)in parameter modifier (C# Reference)

La palabra clave in hace que los argumentos se pasen por referencia.The in keyword causes arguments to be passed by reference. Hace que el parámetro formal sea un alias para el argumento, que debe ser una variable.It makes the formal parameter an alias for the argument, which must be a variable. En otras palabras, cualquier operación en el parámetro se realiza en el argumento.In other words, any operation on the parameter is made on the argument. Es como las palabras clave ref o out, salvo que el método al que se llama no puede modificar los argumentos in.It is like the ref or out keywords, except that in arguments cannot be modified by the called method. Mientras que los argumentos ref se pueden modificar, el método llamado debe modificar los argumentos out y esas modificaciones se pueden observar en el contexto de la llamada.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;
}

En el ejemplo anterior se muestra que el modificador in no suele ser necesario en el sitio de llamada,The preceding example demonstrates that the in modifier is usually unnecessary at the call site. sino que solo lo es en la declaración del método.It is only required in the method declaration.

Nota

Además, la palabra clave in puede usarse con un parámetro de tipo genérico para especificar que el parámetro de tipo es contravariante, parte de una instrucción foreach o de una cláusula join de una consulta de 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 más información sobre el uso de la palabra clave in en esos contextos, vea in, que además incluye vínculos a todos estos usos.For more information on the use of the in keyword in these contexts, see in, which provides links to all those uses.

Las variables que se han pasado como argumentos in deben inicializarse antes de pasarse en una llamada de método.Variables passed as in arguments must be initialized before being passed in a method call. Sin embargo, es posible que el método llamado no asigne ningún valor o modifique el argumento.However, the called method may not assign a value or modify the argument.

El modificador de parámetro in está disponible en C# 7.2 y versiones posteriores.The in parameter modifier is available in C# 7.2 and later. Las versiones anteriores generan el error del compilador CS8107 ("Feature 'readonly references' is not available in C# 7.0.Previous versions generate compiler error CS8107 ("Feature 'readonly references' is not available in C# 7.0. Please use language version 7.2 or greater.") (La característica "readonly references" no está disponible en C# 7.0. Use la versión de lenguaje 7.2 o superior"). Para configurar la versión del lenguaje de compilador, vea Seleccionar la versión del lenguaje C#.Please use language version 7.2 or greater.") To configure the compiler language version, see Select the C# language version.

Las palabras clave in, ref y out no se consideran parte de la firma del método con el fin de resolver la sobrecarga.The in, ref, and out keywords are not considered part of the method signature for the purpose of overload resolution. Por lo tanto, los métodos no pueden sobrecargarse si la única diferencia es que un método toma un argumento ref o in y el otro toma un 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 ejemplo, el código siguiente, no se compilará: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) { }
}

Está permitida la sobrecarga en función de la presencia de in:Overloading based on the presence of in is allowed:

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

Reglas de resolución de sobrecargaOverload resolution rules

Puede comprender las reglas de resolución de sobrecarga de métodos por valor frente a argumentos in mediante la comprensión de la motivación de argumentos in.You can understand the overload resolution rules for methods with by value vs. in arguments by understanding the motivation for in arguments. Definir métodos usando parámetros in es una optimización del rendimiento potencial.Defining methods using in parameters is a potential performance optimization. Algunos argumentos de tipo struct pueden tener un gran tamaño y, cuando se llama a métodos en bucles de pequeñas dimensiones o rutas de acceso de código crítico, el costo de copiar esas estructuras resulta crucial.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. Los métodos declaran parámetros in para especificar qué argumentos pueden pasarse por referencia sin ningún riesgo porque el método llamado no modifica el estado de ese 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. Al pasar esos argumentos por referencia se evita la copia (potencialmente) costosa.Passing those arguments by reference avoids the (potentially) expensive copy.

Especificar in en argumentos en el sitio de llamada suele ser opcional.Specifying in for arguments at the call site is typically optional. No hay ninguna diferencia semántica entre pasar argumentos por valor y pasarlos por referencia mediante el modificador in.There is no semantic difference between passing arguments by value and passing them by reference using the in modifier. El modificador in en el sitio de llamada es opcional porque no es necesario indicar que podría cambiarse el valor del argumento.The in modifier at the call site is optional because you don't need to indicate that the argument's value might be changed. Se agrega explícitamente el modificador in en el sitio de llamada para garantizar que el argumento se pasa por referencia, y no por valor.You explicitly add the in modifier at the call site to ensure the argument is passed by reference, not by value. Usar explícitamente in tiene los dos efectos siguientes:Explicitly using in has the following two effects:

El primero es que, al especificar in en el sitio de llamada, se fuerza al compilador a seleccionar un método definido con un parámetro in coincidente.First, specifying in at the call site forces the compiler to select a method defined with a matching in parameter. En caso contrario, cuando dos métodos se diferencian solo en presencia de in, la sobrecarga por valor es una coincidencia mejor.Otherwise, when two methods differ only in the presence of in, the by value overload is a better match.

El segundo es que, al especificar in declara su intención para pasar un argumento por referencia.Second, specifying in declares your intent to pass an argument by reference. Los argumentos usados con in deben representar una ubicación a la que se pueda hacer referencia directamente.The argument used with in must represent a location that can be directly referred to. Se aplican las mismas reglas generales para los argumentos out y ref: no se pueden usar constantes, propiedades normales u otras expresiones que produzcan valores.The same general rules for out and ref arguments apply: You cannot use constants, ordinary properties, or other expressions that produce values. En caso contrario, si se omite in en el sitio de llamada, se informa al compilador de que le permitirá crear una variable temporal para pasar por referencia de solo lectura para el 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. El compilador crea una variable temporal para superar varias restricciones con argumentos in:The compiler creates a temporary variable to overcome several restrictions with in arguments:

  • Una variable temporal permite constantes en tiempo de compilación como parámetros in.A temporary variable allows compile-time constants as in parameters.
  • Una variable temporal permite propiedades u otras expresiones para parámetros in.A temporary variable allows properties, or other expressions for in parameters.
  • Una variable temporal permite argumentos en los que hay una conversión implícita desde el tipo de argumento hacia el tipo de parámetro.A temporary variable allows arguments where there is an implicit conversion from the argument type to the parameter type.

En todas las instancias anteriores, el compilador crea una variable temporal que almacena el valor de la constante, la propiedad u otra expresión.In all the preceding instances, the compiler creates a temporary variable that stores the value of the constant, property, or other expression.

Estas reglas se muestran en este código: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`

Supongamos ahora que hay disponible otro método que usa argumentos por valor.Now, suppose another method using by value arguments was available. Los resultados cambian como se muestra en este código: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`

La única llamada de método donde se pasa el argumento por referencia es la última.The only method call where the argument is passed by reference is the final one.

Nota

El código anterior usa int como el tipo de argumento para simplificar el trabajo.The preceding code uses int as the argument type for simplicity. Como int no es más grande que una referencia en la mayoría de máquinas modernas, no supone ninguna ventaja pasar un único int como una referencia de solo lectura.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.

Limitaciones de los parámetros inLimitations on in parameters

Las palabras clave in, ref y out no pueden usarse para estos tipos de métodos:You can't use the in, ref, and out keywords for the following kinds of methods:

  • Métodos asincrónicos, que se definen mediante el uso del modificador async.Async methods, which you define by using the async modifier.
  • Métodos de iterador, que incluyen una instrucción yield return o yield break.Iterator methods, which include a yield return or yield break statement.

Especificación del lenguaje C#C# Language Specification

Para obtener más información, consulte la Especificación del lenguaje C#.For more information, see the C# Language Specification. La especificación del lenguaje es la fuente definitiva de la sintaxis y el uso de C#.The language specification is the definitive source for C# syntax and usage.

Vea tambiénSee also