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 deref
oout
(excepto en un constructor) - CS0199: : un campo
static readonly
no se puede usar como valor deref
oout
(excepto en un constructor) - CS0206: es posible que no se use una propiedad o indexador que no devuelva referencias como un valor
out
oref
- CS0631:
ref
yout
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
yout
- CS1510: un valor
ref
oout
debe ser una variable asignable - CS1605: no se puede usar la variable como un valor
ref
oout
porque es de solo lectura - CS1623: los iteradores no pueden tener parámetros
ref
,in
oout
parámetros - CS1649: Miembros de un campo de
readonly
no se puede usar como valor deref
oout
(excepto en un constructor) - CS1651: Los campos de un campo estático de solo lectura no se pueden usar como un valor
ref
oout
(excepto en un constructor estático) - CS1655: No se pueden usar campos de tipo como
ref
oout
valor - CS1657: no se puede usar la variable como
ref
oout
valor - CS1741: un parámetro
ref
oout
no puede tener un valor predeterminado - CS1939: no se puede pasar la variable de intervalo como un parámetro
out
oref
- CS1988: los métodos asincrónicos no pueden tener parámetros
ref
,in
oout
- CS7084: es posible que un evento de Windows Runtime no se pase como parámetro
out
oref
. - 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
oout
- 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 unref
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 oout
porque es una variable de solo lectura - CS8330: los miembros de la variable no se pueden usar como un valor
ref
oout
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 "", "
ref
in
" 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 deref
. - 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
oout
- 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ámetroin
es equivalente ain
. Considere la posibilidad de usarin
en su lugar. - CS9192: el argumento debe pasarse con la palabra clave
ref
oin
. - CS9193: el argumento debe ser una variable porque se pasa a un
ref readonly
pará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
, peroref readonly
solo se debe usar para las referencias. Considere la posibilidad de declarar el parámetro comoin
. - 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:
- Sintaxis incorrecta: la sintaxis de la declaración o el uso no es válida.
- Construcciones de lenguaje en
ref
las que las variables no son válidas: algunas expresiones de C# no permiten variables. Normalmente esto se debe a que el análisis de seguridad ref no se puede realizar de forma confiable. - Expresión de valor que se usa cuando se necesita una variable de referencia: la expresión usada como variable de referencia debe ser una variable, no una expresión de valor.
- Variables de referencia grabables que hacen referencia a variables de solo lectura: una referencia a una variable readonly no se puede pasar mediante referencia grabable.
- infracciones de seguridad ref: una variable de referencia no puede hacer referencia a una variable que tenga un contexto más estrecho. Esto significaría que la variable de referencia podría hacer referencia a la memoria no válida.
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 struct
o 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 deref
.
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, useref
.
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
yout
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
yout
- CS1623: los iteradores no pueden tener parámetros
ref
,in
oout
- CS1741: Un parámetro
ref
oout
no puede tener un valor predeterminado - CS1939: no se puede pasar la variable de intervalo como un parámetro
out
oref
- CS1988: los métodos asincrónicos no pueden tener parámetros
ref
,in
oout
- CS7084: es posible que un evento de Windows Runtime no se pase como parámetro
out
oref
. - 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
, peroref readonly
solo se debe usar para las referencias. Considere la posibilidad de declarar el parámetro comoin
. - 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
yout
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
. Quiteref
de una expresión o agréguela a la otra. Si es una expresión condicionalref
, ambas expresiones deben ser del mismo tipo. - Los parámetros
ref
yout
no pueden tener valores predeterminados. Quite el modificadorref
oout
, 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 lambdaasync
. - 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
yout
. Por ejemplo, una interfaz declaravoid M(ref int i)
y otra interfaz declaravoid 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
oref
- CS1510: un valor
ref
oout
debe ser una variable asignable
Advertencias:
- CS9191: el modificador
ref
para el argumento correspondiente al parámetroin
es equivalente ain
. Considere la posibilidad de usarin
en su lugar. - CS9192: el argumento debe pasarse con la palabra clave
ref
oin
. - CS9193: el argumento debe ser una variable porque se pasa a un
ref readonly
pará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 valorref
oout
(excepto en un constructor) - CS0199: un campo
static readonly
no se puede usar como un valorref
oout
(excepto en un constructor estático) - CS1605: no se puede usar una variable como valor
ref
oout
porque es de solo lectura - CS1649: los miembros de un campo
readonly
no se pueden usar como un valorref
oout
(excepto en un constructor) - CS1651: los campos de un campo
static readonly
no se puede usar como un valorref
oout
(excepto en un constructor estático) - CS1655: no se pueden usar campos de tipo como valor
ref
oout
- CS1657: no se puede usar una variable como valor
ref
oout
- CS8329: no se puede usar la variable como un valor
ref
oout
porque es una variable de solo lectura - CS8330: los miembros de la variable no se pueden usar como un valor
ref
oout
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
oout
- 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
oout
- 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.