Compartir a través de


Errores y advertencias asociados con parámetros de referencia, variables y devoluciones

Se pueden generar los siguientes errores cuando se trabaja con variables de referencia:

  • CS0192: : un campo readonly no se puede usar como valor de ref o out (excepto en un constructor)
  • CS0199: : un campo static readonly no se puede usar como valor de ref o out (excepto en un constructor)
  • CS0206: es posible que no se use una propiedad o indexador que no devuelva referencias como un valor out o ref
  • CS0631: ref y out no son válidos en este contexto
  • CS0767: no se puede heredar la interfaz con los parámetros de tipo especificados porque hace que el método contenga sobrecargas que solo difieren en ref y out
  • CS1510: un valor ref o out debe ser una variable asignable
  • CS1605: no se puede usar la variable como un valor ref o out porque es de solo lectura
  • CS1623: los iteradores no pueden tener parámetros ref, in o outparámetros
  • CS1649: Miembros de un campo de readonly no se puede usar como valor de ref o out (excepto en un constructor)
  • CS1651: Los campos de un campo estático de solo lectura no se pueden usar como un valor ref o out (excepto en un constructor estático)
  • CS1655: No se pueden usar campos de tipo como ref o outvalor
  • CS1657: no se puede usar la variable como ref o outvalor
  • CS1741: un parámetro ref o out no puede tener un valor predeterminado
  • CS1939: no se puede pasar la variable de intervalo como un parámetro out o ref
  • CS1988: los métodos asincrónicos no pueden tener parámetros ref, in o out
  • CS7084: es posible que un evento de Windows Runtime no se pase como parámetro out o ref.
  • CS8166: no se pude devolver por referencia un parámetro porque no es de tipo ref
  • CS8167: no se puede devolver un miembro del parámetro por referencia, porque no es un parámetro ref o out
  • CS8168: la variable local no se puede devolver por referencia porque no es de tipo ref
  • CS8169: no se puede devolver un miembro de la variable local por referencia porque no es una variable local de tipo ref
  • CS8196: Referencia a una variable de salida con tipo implícito no se permite en la misma lista de argumentos.
  • CS8325: 'await' no se puede usar en una expresión que contenga un ref operador condicional
  • CS8326: Ambos valores de operador condicional deben ser valores ref o ninguno de ellos debe ser un valor ref
  • CS8327: la expresión debe ser de tipo correcto para que coincida con el valor ref alternativo
  • CS8329: No se puede usar la variable como un ref valor o out porque es una variable de solo lectura
  • CS8330: los miembros de la variable no se pueden usar como un valor ref o out porque es una variable de solo lectura
  • CS8331: no se puede asignar a la variable ni usarla como el lado derecho de una asignación ref porque es una variable de solo lectura
  • CS8332: No se puede asignar a un miembro de la variable o usarlo como lado derecho de una ref asignación porque es una variable de solo lectura
  • CS8337: el primer parámetro de un método de extensión 'ref' debe ser un tipo de valor o un tipo genérico restringido a struct.
  • CS8338: el primer parámetro 'in' o 'ref readonly' del método de extensión debe ser un tipo de valor concreto (no genérico).
  • CS8351: Las ramas de un ref operador condicional no pueden hacer referencia a variables con ámbitos de declaración incompatibles
  • CS8373: El lado izquierdo de una asignación de ref debe ser una variable ref.
  • CS8374: No se puede asignar el origen de referencia tiene un ámbito de escape más estrecho que el destino.
  • CS8388: Una out variable no se puede declarar como una variable local ref
  • CS8977: No se puede usar "", "refin" o "out" en la firma de un método con atributos "UnmanagedCallersOnly".
  • CS9072: Una variable de deconstrucción no se puede declarar como ref local
  • CS9077: No se puede devolver un parámetro por referencia a través de un ref parámetro; solo se puede devolver en una instrucción return
  • CS9078: No se puede devolver por referencia un miembro del parámetro a través de un parámetro ref; solo se puede devolver en una instrucción "return"
  • CS9079: no se puede asignar referencia porque el origen solo puede escapar el método actual a través de una instrucción return.
  • CS9096: no se puede asignar referencia porque el origen tiene un ámbito de escape de valor más amplio que el destino que permite la asignación a través del origen de valores con ámbitos de escape más estrechos que el destino.
  • CS9101: UnscopedRefAttribute solo se puede aplicar a propiedades y métodos de instancia de interfaz virtual y estructura, y no se puede aplicar a constructores o miembros de solo inicialización.
  • CS9102: UnscopedRefAttribute no se puede aplicar a una implementación de interfaz porque el miembro implementado no tiene este atributo.
  • CS9104: no se puede usar un using recurso de instrucción de tipo en métodos asincrónicos ni expresiones lambda asincrónicas.
  • CS9190: readonly el modificador debe especificarse después de ref.
  • CS9199: un parámetro ref readonly no puede tener el atributo Out.

Las siguientes advertencias se generan cuando las variables de referencia se usan incorrectamente:

  • CS9085: esta variable de asignación de referencias pero el destino tiene un ámbito de escape más estrecho que el origen.
  • CS9086: Las ramas del operador condicional ref hacen referencia a variables con ámbitos de declaración incompatibles
  • CS9087: devuelve un parámetro por referencia, pero no es un ref parámetro
  • CS9089: devuelve por referencia un miembro del parámetro que no es un parámetro ref o out
  • CS9091: devuelve por referencia la variable local, pero no es una variable local de tipo ref
  • CS9092: Esto devuelve por referencia un miembro de la variable local, pero no es una variable local de tipo ref
  • CS9093: esta referencia asigna, pero el origen solo puede escapar del método actual a través de una instrucción return.
  • CS9094: Devuelve un parámetro por referencia "{0}" a través de un parámetro ref; pero solo se puede devolver de forma segura en una instrucción "return"
  • CS9095: Devuelve por referencia un miembro del parámetro "{0}" a través de un parámetro ref; pero solo se puede devolver de forma segura en una instrucción "return"
  • CS9097: esta referencia asigna, pero el origen tiene un ámbito de escape de valor más amplio que el destino que permite la asignación a través del destino de valores con ámbitos de escape más estrechos que el origen.
  • CS9191: el modificador ref para el argumento correspondiente al parámetro in es equivalente a in. Considere la posibilidad de usar in en su lugar.
  • CS9192: el argumento debe pasarse con la palabra clave ref o in.
  • CS9193: el argumento debe ser una variable porque se pasa a un ref readonlyparámetro
  • CS9195: El argumento debe pasarse con la in palabra clave
  • CS9196: el modificador de tipo de referencia del parámetro no coincide con el parámetro correspondiente en miembro invalidado o implementado.
  • CS9197: el modificador de tipo de referencia del parámetro no coincide con el parámetro correspondiente en el miembro oculto.
  • CS9198: el modificador de tipo de referencia del parámetro no coincide con el parámetro correspondiente en el destino.
  • CS9200: se especifica un valor predeterminado para el parámetro ref readonly, pero ref readonly solo se debe usar para las referencias. Considere la posibilidad de declarar el parámetro como in.
  • CS9201: El campo Ref debe asignarse antes de su uso.
  • CS9265: el campo nunca se asigna a y siempre tendrá su valor predeterminado (referencia nula)

Estos errores y advertencias siguen estos temas:

En este artículo se usa la variable de referencia de términos como un término general para un parámetro declarado con uno de los modificadores in, ref readonly, ref o out, o una variable local ref, un campo ref en un ref structo un ref devuelto. Una variable de referencia hace referencia a otra variable, denominada referente.

Sintaxis incorrecta

Estos errores indican que está usando una sintaxis incorrecta con respecto a las variables de referencia:

  • CS8373: La parte izquierda de una asignación de ref debe ser una referencia local o un parámetro.
  • CS8388: una out variable no se puede declarar como local ref.
  • CS9190: readonly el modificador debe especificarse después de ref.

Puede corregir el error con uno de estos cambios:

  • El operando izquierdo de un operador = ref debe ser una variable de referencia. Para obtener más información sobre la sintaxis correcta, consulte variables de referencia.
  • El modificador de parámetro ref readonly debe estar en ese orden. readonly ref no es un modificador de parámetro legal. Cambie el orden de las palabras.
  • No se puede declarar una variable local como out. Para declarar una variable de referencia local, use ref.

Restricciones de variables de referencia

Los siguientes errores indican que no se puede usar una variable de referencia en la que tenga una:

  • CS0631: ref y out no son válidos en este contexto
  • CS0767: no se puede heredar la interfaz con los parámetros de tipo especificados porque hace que el método contenga sobrecargas que solo difieren en ref y out
  • CS1623: los iteradores no pueden tener parámetros ref, in o out
  • CS1741: Un parámetroref o out no puede tener un valor predeterminado
  • CS1939: no se puede pasar la variable de intervalo como un parámetro out o ref
  • CS1988: los métodos asincrónicos no pueden tener parámetros ref, in o out
  • CS7084: es posible que un evento de Windows Runtime no se pase como parámetro out o ref.
  • CS8196: Referencia a una variable out con tipo implícito no se permite en la misma lista de argumentos.
  • CS8325: 'await' no se puede usar en una expresión que contenga un ref operador condicional
  • CS8326: ambos valores de operador condicional deben ser valores ref o ninguno puede ser un valor ref
  • CS8327: la expresión debe ser de tipo correcto para que coincida con el valor ref alternativo
  • CS8337: El primer parámetro de un método de extensión 'ref' debe ser un tipo de valor o un tipo genérico restringido a struct.
  • CS8338: el primer parámetro 'in' o 'ref readonly' del método de extensión debe ser un tipo de valor concreto (no genérico).
  • CS8977: No se puede usar 'ref', 'in', o 'out' en la firma de un método con "UnmanagedCallersOnly".
  • CS9072: Una variable de deconstrucción no se puede declarar como ref local
  • CS9104: no se puede usar un using recurso de instrucción de tipo en métodos asincrónicos ni expresiones lambda asincrónicas.
  • CS9199: Un parámetro ref readonly no puede tener el atributo Out.

Las siguientes advertencias indican que no se debe usar una variable de referencia y podría no ser segura:

  • CS9196: el modificador de tipo de referencia del parámetro no coincide con el parámetro correspondiente en miembro invalidado o implementado.
  • CS9197: el modificador de tipo de referencia del parámetro no coincide con el parámetro correspondiente en el miembro oculto.
  • CS9198: el modificador de tipo de referencia del parámetro no coincide con el parámetro correspondiente en el destino.
  • CS9200: se especifica un valor predeterminado para el parámetro ref readonly, pero ref readonly solo se debe usar para las referencias. Considere la posibilidad de declarar el parámetro como in.
  • CS9201: El campo Ref debe asignarse antes de su uso.
  • CS9265: el campo nunca se asigna a y siempre tendrá su valor predeterminado (referencia nula)

Para corregir el error, quite la variable de referencia en la que no se permite:

  • Quite los parámetros in, ref y out de los indizadores, los iteradores y los métodos asincrónicos.
  • Quite las expresiones condicionales ref (? :) que incluyen una await.
  • Quite el modificador ref del primer parámetro de un método de extensión donde ese tipo no sea un tipo de valor o un tipo genérico restringido como un tipo de valor.
  • Ambas o ninguna [expresiones de operador condicional] deben ser variables ref. Quite ref de una expresión o agréguela a la otra. Si es una expresión condicional ref, ambas expresiones deben ser del mismo tipo.
  • Los parámetros ref y out no pueden tener valores predeterminados. Quite el modificador ref o out, o quite el valor predeterminado.
  • Una declaración de variable implícitamente tipada out no puede aparecer también en otra parte de la misma lista de argumentos.
  • No se pueden colocar variables de referencia en una instrucción using en los métodos expresiones lambda async.
  • La variable de rango de una expresión de consulta LINQ no se puede pasar por referencia.
  • No se puede deconstruir un objeto en variables de referencia. Reemplace las variables de referencia por variables de valor.
  • No se pueden implementar varias interfaces en las que las sobrecargas de método solo difieren en ref y out. Por ejemplo, una interfaz declara void M(ref int i) y otra interfaz declara void M(out int i). Una clase no puede implementar ambas interfaces porque los métodos no se pueden distinguir. Solo puede implementar una de esas interfaces.
  • Los métodos con atributos con System.Runtime.InteropServices.UnmanagedCallersOnlyAttribute no pueden usar parámetros de referencia.
  • No se puede pasar un evento de Windows Runtime como una variable de referencia.
  • Un parámetro ref readonly no puede tener aplicado System.Runtime.InteropServices.OutAttribute en la API de comunicación remota.
  • Inicialice un ref campo en el constructor o como inicializador de campo.

Restricciones unscoped ref

El calificador unscoped en parámetros ref no se permite en algunas ubicaciones:

  • CS9101: UnscopedRefAttribute solo se puede aplicar a propiedades y métodos de instancia de interfaz virtual y estructura, y no se puede aplicar a constructores o miembros de solo inicialización.
  • CS9102: UnscopedRefAttribute no se puede aplicar a una implementación de interfaz porque el miembro implementado no tiene este atributo.

Debe quitar el modificador unscoped en la declaración de parámetro que provocó el error.

Las variables de referencia requieren un referente

Debe proporcionar una variable como argumento a un parámetro de referencia, una devolución de referencia o una asignación local ref:

  • CS0206: es posible que no se use una propiedad o indexador que no devuelva referencias como un valor out o ref
  • CS1510: un valor ref o out debe ser una variable asignable

Advertencias:

  • CS9191: el modificador ref para el argumento correspondiente al parámetro in es equivalente a in. Considere la posibilidad de usar in en su lugar.
  • CS9192: el argumento debe pasarse con la palabra clave ref o in.
  • CS9193: el argumento debe ser una variable porque se pasa a un ref readonlyparámetro
  • CS9195: el argumento debe pasarse con la palabra clave in

El compilador emite estos errores cuando se usa una expresión que calcula un valor en el que se debe usar una variable. Debe almacenar el resultado de esa expresión en una variable para usarla. Por ejemplo, las propiedades y los indexadores devuelven valores, no variables. Debe almacenar el resultado en una variable y pasar una referencia a esa variable.

Las variables de referencia grabable requieren un referente grabable

Una variable de referencia grabable requiere que el referente también sea grabable. Los siguientes errores indican que la variable no se puede escribir:

  • CS0192: un campo readonly no se puede usar como un valor ref o out (excepto en un constructor)
  • CS0199: un campo static readonly no se puede usar como un valor ref o out (excepto en un constructor estático)
  • CS1605: no se puede usar una variable como valor ref o out porque es de solo lectura
  • CS1649: los miembros de un campo readonly no se pueden usar como un valor ref o out (excepto en un constructor)
  • CS1651: los campos de un campo static readonly no se puede usar como un valor ref o out (excepto en un constructor estático)
  • CS1655: no se pueden usar campos de tipo como valor ref o out
  • CS1657: no se puede usar una variable como valor ref o out
  • CS8329: no se puede usar la variable como un valor ref o out porque es una variable de solo lectura
  • CS8330: los miembros de la variable no se pueden usar como un valor ref o out porque es una variable de solo lectura
  • CS8331: no se puede asignar a la variable ni usarla como el lado derecho de una asignación ref porque es una variable de solo lectura
  • CS8332: no se puede asignar a un miembro de la variable o usarlo como lado derecho de una asignación ref porque es una variable de solo lectura

Entre los ejemplos de variables que no se pueden escribir se incluyen:

  • Campos de solo lectura, tanto de instancia como de estáticos.
  • Miembros de campos readonly.
  • La variable this.
  • La variable de iteración foreach
  • Una variable de uso o una variable fija.

Debe copiar el valor y pasar una referencia a la copia.

Infracciones de seguridad ref

El compilador realiza un seguimiento del contexto seguro de los referentes y las variables de referencia. El compilador emite errores o advertencias en código no seguro, cuando una variable de referencia hace referencia a una variable de referencia que ya no es válida. El referente debe tener un contexto seguro que sea al menos tan amplio como el contexto seguro ref de la variable de referencia. Infringir estas comprobaciones de seguridad significa que la variable de referencia accede a la memoria aleatoria en lugar de a la variable de referencia.

  • CS8166: no se puede devolver por referencia un parámetro porque no es de tipo ref
  • CS8167: no se puede devolver un miembro del parámetro por referencia, porque no es un parámetro ref o out
  • CS8168: la variable local no se puede devolver por referencia porque no es de tipo ref
  • CS8169: no se puede devolver un miembro de la variable local por referencia porque no es una variable local de tipo ref
  • CS8345: el campo o la propiedad implementada automáticamente no pueden ser de tipo a menos que sea un miembro de instancia de un ref struct.
  • CS8351: las ramas de un operador condicional ref no pueden hacer referencia a variables con ámbitos de declaración incompatibles
  • CS8374: no se puede asignar el origen de referencia tiene un ámbito de escape más estrecho que el destino.
  • CS9077: no se puede devolver un parámetro por referencia a través de un parámetro ref; solo se puede devolver en una instrucción return
  • CS9078: no se puede devolver por referencia un miembro del parámetro a través de un parámetro ref; solo se puede devolver en una instrucción "return"
  • CS9079: no se puede asignar referencia porque el origen solo puede escapar el método actual a través de una instrucción return.
  • CS9096: no se puede asignar el origen a destino porque el origen tiene un ámbito de escape de valor más amplio que el destino que permite la asignación a través del destino de valores con ámbitos de escape más estrechos que el origen.

Advertencias:

  • CS9085: este origen asigna el origen al destino, pero el origen tiene un ámbito de escape más estrecho que el destino.
  • CS9086: las ramas del operador condicional ref hacen referencia a variables con ámbitos de declaración incompatibles
  • CS9087: devuelve un parámetro por referencia, pero no es un parámetro ref
  • CS9089: devuelve por referencia un miembro del parámetro que no es un parámetro ref o out
  • CS9091: devuelve por referencia la variable local, pero no es una variable local de tipo ref
  • CS9092: devuelve por referencia un miembro de la variable local, pero no es una variable local de tipo ref
  • CS9093: esta referencia asigna el origen al destino, pero el origen solo puede escapar del método actual a través de una instrucción return.
  • CS9094: devuelve un parámetro por referencia "{0}" a través de un parámetro ref; pero solo se puede devolver de forma segura en una instrucción "return"
  • CS9095: devuelve por referencia un miembro del parámetro "{0}" a través de un parámetro ref; pero solo se puede devolver de forma segura en una instrucción "return"
  • CS9097: esta referencia asigna el origen al destino, pero el origen tiene un ámbito de escape de valor más amplio que el destino que permite la asignación a través del destino de valores con ámbitos de escape más estrechos que el origen.

El compilador usa el análisis estático para determinar si el referente es válido en todos los puntos en los que se puede usar la variable de referencia. Debe refactorizar el código para que el referente permanezca válido en todas las ubicaciones donde la variable de referencia pueda hacer referencia a él. Para obtener más información sobre las reglas para la seguridad de referencias, consulte el estándar de C# en contextos seguros de referencia.