Erros e avisos associados a parâmetros de referência, variáveis e retornos

Os seguintes erros podem ser gerados quando você está trabalhando com variáveis de referência:

  • CS0192: um campo readonly não pode ser usado como um valor ref ou out (exceto em um construtor)
  • CS0199: um campo static readonly não pode ser usado como um valor ref ou out (exceto em um construtor estático)
  • CS0206: propriedades ou indexadores que não retornem referências talvez não possam ser usados como um valor out ou ref
  • CS0631: ref e out não são válidos neste contexto
  • CS0767: não é possível herdar a interface com os parâmetros de tipo especificados, porque isso faz com que o método contenha sobrecargas que diferem apenas em ref e out
  • CS1510: um valor ref ou out deve ser uma variável atribuível
  • CS1605: não é possível usar a variável como um valor ref ou out porque ela é somente leitura
  • CS1623: os iteradores não podem ter parâmetros ref, in ou out
  • CS1649: os membros de um campo readonly não podem ser usados como um valor ref ou out (exceto em um construtor)
  • CS1651: campos de um campo estático somente leitura não podem ser usados como um valor ref ou out (exceto em um construtor estático)
  • CS1655: não é possível usar campos do tipo como um valor ref ou out
  • CS1657: não é possível usar a variável como um valor ref ou out
  • CS1741: um parâmetro ref ou out não pode ter um valor padrão
  • CS1939: não é possível passar a variável de intervalo como um parâmetro out ou ref
  • CS1988: métodos assíncronos não podem ter parâmetros ref, in ou out
  • CS7084: um evento do Windows Runtime pode não ser passado como um parâmetro out ou ref.
  • CS8166: não é possível retornar um parâmetro por referência porque ele não é um parâmetro ref
  • CS8167: não é possível retornar por referência um membro do parâmetro porque ele não é um parâmetro ref ou out
  • CS8168: não é possível retornar o local por referência porque não é um local de referência
  • CS8169: não é possível retornar um membro da variável local por referência porque ele não é um local de referência
  • CS8196: Referência a uma variável digitada implicitamente não é permitida na mesma lista de argumentos.
  • CS8325: "await" não pode ser usado em uma expressão que contém um operador condicional ref
  • CS8326: ambos os valores de operador condicional devem ser valores de referência ou nenhum deles pode ser um valor de referência
  • CS8327: a expressão deve ser do tipo correto para corresponder ao valor de referência alternativo
  • CS8329: não é possível usar a variável como um valor ref ou out porque ela é uma variável somente leitura
  • CS8330: os membros da variável não podem ser usados como um valor ref ou out porque é uma variável somente leitura
  • CS8331: não é possível atribuir à variável ou usá-la como o lado direito de uma atribuição ref porque ela é uma variável somente leitura
  • CS8332: não é possível atribuir a um membro da variável ou usá-la como o lado direito de uma atribuição ref porque ela é uma variável somente leitura
  • CS8337: o primeiro parâmetro de um método de extensão "ref" deve ser um tipo de valor ou um tipo genérico restrito ao struct.
  • CS8338: o primeiro parâmetro "in" ou "ref readonly" do método de extensão deve ser um tipo de valor concreto (não genérico).
  • CS8345: a propriedade de campo ou implementada automaticamente não pode ser do tipo, a menos que seja um membro de instância de um ref struct.
  • CS8351: branches de um operador condicional ref não podem se referir a variáveis com escopos de declaração incompatíveis
  • CS8373: o lado esquerdo de uma atribuição ref deve ser uma variável de referência.
  • CS8374: não é possível atribuir novamente, a origem tem um escopo de escape mais estreito do que o destino.
  • CS8388: uma variável out não pode ser declarada como uma referência local
  • CS8977: não é possível usar "ref", "in" ou "out" na assinatura de um método atribuído com "UnmanagedCallersOnly".
  • CS9072: uma variável de desconstrução não pode ser declarada como uma referência local
  • CS9077: não é possível retornar um parâmetro por referência por meio de um parâmetro ref; ele só pode ser retornado em uma instrução return
  • CS9078: não é possível retornar por referência um membro do parâmetro por meio de um parâmetro ref; ele só pode ser retornado em uma instrução return
  • CS9079: não é possível atribuir novamente porque a origem só pode escapar do método atual por meio de uma instrução de retorno.
  • CS9096: não é possível atribuir novamente porque a origem tem um escopo de escape de valor mais amplo do que o destino, permitindo a atribuição por meio de fonte de valores com escopos de escape mais estreitos do que o destino.
  • CS9101: UnscopedRefAttribute só pode ser aplicado a métodos e propriedades de instância de struct e não pode ser aplicado a construtores ou membros somente init.
  • CS9102: UnscopedRefAttribute não pode ser aplicado a uma implementação de interface.
  • CS9104: um recurso de instrução de uso do tipo não pode ser usado em métodos assíncronos ou expressões lambda assíncronas.
  • CS9190: o modificador readonly deve ser especificado após ref.
  • CS9199: um parâmetro ref readonly não pode ter o atributo Out.

Os seguintes avisos são gerados quando variáveis de referência são usadas incorretamente:

  • CS9085: essa referência atribui variável, mas o destino tem um escopo de escape mais estreito que a origem.
  • CS9086: os branches do operador condicional ref referem-se a variáveis com escopos de declaração incompatíveis
  • CS9087: isso retorna um parâmetro por referência, mas não é um parâmetro ref
  • CS9089: isso retorna por referência um membro do parâmetro que não é um parâmetro ref ou out
  • CS9091: isso retorna o local por referência, mas não é uma referência local
  • CS9092: isso retorna um membro do local por referência, mas não é uma referência local
  • CS9093: essa referência atribui, mas a origem só pode escapar do método atual por meio de uma instrução de retorno.
  • CS9094: isso retorna um parâmetro por referência por meio de um parâmetro ref; mas ele só pode ser retornado com segurança em uma instrução return
  • CS9095: isso retorna por referência um membro do parâmetro por meio de um parâmetro ref; mas ele só pode ser retornado com segurança em uma instrução return
  • CS9097: essa referência atribui, mas a origem tem um escopo de escape de valor mais amplo do que o destino, o que permite a atribuição por meio de destino de valores com escopos de escape mais estreitos do que a origem.
  • CS9191: o modificador ref do argumento correspondente ao parâmetro in é equivalente a in. Considere usar in em vez disso.
  • CS9192: o argumento deve ser passado com a palavra-chave ref ou in.
  • CS9193: o argumento deve ser uma variável porque é passado para um parâmetro ref readonly
  • CS9195: o argumento deve ser passado com a palavra-chave in
  • CS9196: o modificador de tipo de referência do parâmetro não corresponde ao parâmetro correspondente no membro substituído ou implementado.
  • CS9197: o modificador de tipo de referência do parâmetro não corresponde ao parâmetro correspondente no membro oculto.
  • CS9198: o modificador de tipo de referência do parâmetro não corresponde ao parâmetro correspondente no destino.
  • CS9200: um valor padrão é especificado para o parâmetro ref readonly, mas ref readonly deve ser usado apenas para referências. Considere declarar o parâmetro como in.
  • CS9201: o campo Ref deve ser atribuído novamente antes do uso.

Estes erros e avisos seguem estes temas:

Este artigo usa a variável de referência do termo como um termo geral para um parâmetro declarado com um dos modificadores in, ref readonly, ref ou out ou uma variável local ref, um campo ref em um ref struct ou um retorno ref. Uma variável de referência refere-se a outra variável, chamada de referencial.

Sintaxe incorreta

Esses erros indicam que você está usando a sintaxe incorreta em relação às variáveis de referência:

  • CS8373: o lado esquerdo de uma atribuição ref deve ser uma variável de referência.
  • CS8388: uma variável out não pode ser declarada como um local de referência.
  • CS9190: o modificador readonly deve ser especificado após ref.

Você pode corrigir o erro com uma destas alterações:

  • O operando esquerdo de um operador = ref deve ser uma variável de referência. Para obter mais informações sobre a sintaxe correta, confira variáveis de referência.
  • O modificador de parâmetro ref readonly deve estar nessa ordem. readonly ref não é um modificador de parâmetro legal. Alterne a ordem das palavras.
  • Uma variável local não pode ser declarada como out. Para declarar uma variável de referência local, use ref.

Restrições de variável de referência

Os erros a seguir indicam que uma variável de referência não pode ser usada onde você tem:

  • CS0631: ref e out não são válidos neste contexto
  • CS0767: não é possível herdar a interface com os parâmetros de tipo especificados porque isso faz com que o método contenha sobrecargas que diferem apenas em ref e out
  • CS1623: iteradores não podem ter parâmetros ref, in ou out
  • CS1741: Um parâmetro ref ou out não pode ter um valor padrão
  • CS1939: não é possível passar a variável de intervalo como um parâmetro out ou ref
  • CS1988: métodos assíncronos não podem ter parâmetros ref, in ou out
  • CS7084: um evento do Windows Runtime pode não ser passado como um parâmetro out ou ref.
  • CS8196: Referência a uma variável out digitada implicitamente não é permitida na mesma lista de argumentos.
  • CS8325: "await" não pode ser usado em uma expressão que contém um operador condicional ref
  • CS8326: ambos os valores de operador condicional devem ser valores de referência ou nenhum deles pode ser um valor de referência
  • CS8327: a expressão deve ser do tipo correto para corresponder ao valor de referência alternativo
  • CS8337: o primeiro parâmetro de um método de extensão "ref" deve ser um tipo de valor ou um tipo genérico restrito ao struct.
  • CS8338: o primeiro parâmetro "in" ou "ref readonly" do método de extensão deve ser um tipo de valor concreto (não genérico).
  • CS8977: não é possível usar "ref", "in" ou "out" na assinatura de um método atribuído com "UnmanagedCallersOnly".
  • CS9072: uma variável de desconstrução não pode ser declarada como uma referência local
  • CS9104: um recurso de instrução using do tipo não pode ser usado em métodos assíncronos ou expressões lambda assíncronas.
  • CS9199: um parâmetro ref readonly não pode ter o atributo Out.

Os avisos a seguir indicam que uma variável de referência não deve ser usada e pode não ser segura:

  • CS9196: o modificador de tipo de referência do parâmetro não corresponde ao parâmetro correspondente no membro substituído ou implementado.
  • CS9197: o modificador de tipo de referência do parâmetro não corresponde ao parâmetro correspondente no membro oculto.
  • CS9198: o modificador de tipo de referência do parâmetro não corresponde ao parâmetro correspondente no destino.
  • CS9200: um valor padrão é especificado para o parâmetro ref readonly, mas ref readonly deve ser usado apenas para referências. Considere declarar o parâmetro como in.
  • CS9201: o campo Ref deve ser atribuído novamente antes do uso.

Para corrigir o erro, remova a variável de referência onde ela não é permitida:

  • Remova os parâmetros in, ref e out dos indexadores, iteradores e métodos assíncronos.
  • Remova expressões condicionais de referência (? :) que incluem um await.
  • Remova o modificador ref do primeiro parâmetro de um método de extensão em que esse tipo não é um tipo de valor ou um tipo genérico restrito como um tipo de valor.
  • Ambas as [expressões de operador condicional] ou nenhuma delas devem ser variáveis ref. Remova ref de uma expressão ou adicione-o à outra. Se for uma expressão condicional ref, ambas as expressões deverão ser do mesmo tipo.
  • Os parâmetros ref e out não podem ter valores padrão. Remova o modificador ref ou out ou remova o valor padrão.
  • Uma declaração de variável out digitada implicitamente também não pode aparecer em outro lugar na mesma lista de argumentos.
  • Você não pode colocar variáveis de referência em uma instrução using em métodos de expressões lambda async.
  • A variável de intervalo em uma expressão de consulta LINQ não pode ser passada por referência.
  • Não é possível desconstruir um objeto em variáveis de referência. Substitua as variáveis de referência por variáveis de valor.
  • Você não pode implementar várias interfaces em que as sobrecargas de método diferem apenas em ref e out. Por exemplo, uma interface declara void M(ref int i) e outra interface declara void M(out int i). Uma classe não pode implementar ambas as interfaces porque os métodos não são distinguíveis. Você só pode implementar uma dessas interfaces.
  • Métodos atribuídos com System.Runtime.InteropServices.UnmanagedCallersOnlyAttribute não podem usar parâmetros de referência.
  • Um evento de runtime do Windows não pode ser passado como uma variável de referência.
  • Um parâmetro ref readonly não pode ter o System.Runtime.InteropServices.OutAttribute aplicado a ele na API de comunicação remota.

Restrições unscoped ref

O qualificador unscoped em parâmetros ref não é permitido em alguns locais:

  • CS9101: UnscopedRefAttribute só pode ser aplicado a métodos e propriedades de instância de struct e não pode ser aplicado a construtores ou membros somente init.
  • CS9102: UnscopedRefAttribute não pode ser aplicado a uma implementação de interface.

Você deve remover o modificador unscoped na declaração de parâmetro que causou o erro.

As variáveis de referência exigem um referencial

Você deve fornecer uma variável como um argumento para um parâmetro de referência, retorno de referência ou atribuição local ref:

  • CS0206: Uma propriedade ou indexador que não retorna uma referência pode não ser usada como um valor out ou ref
  • CS1510: O valor ref ou out deve ser uma variável atribuível

Avisos:

  • CS9191: O modificador ref do argumento correspondente ao parâmetro in é equivalente a in. Considere usar in em vez disso.
  • CS9192: o argumento deve ser passado com a palavra-chave ref ou in.
  • CS9193: o argumento deve ser uma variável porque é passado para um parâmetro ref readonly
  • CS9195: o argumento deve ser passado com a palavra-chave in

O compilador emite esses erros quando você usa uma expressão que calcula um valor em que uma variável deve ser usada. Você deve armazenar o resultado dessa expressão em uma variável para usá-la. Por exemplo, propriedades e indexadores retornam valores, não variáveis. Você deve armazenar o resultado em uma variável e passar uma referência para essa variável.

Variáveis de referência graváveis exigem um referencial gravável

Uma variável de referência gravável requer que o referencial também seja gravável. Os seguintes erros indicam que a variável não é gravável:

  • CS0192: um campo readonly não pode ser usado como um valor ref ou out (exceto em um construtor)
  • CS0199: um campo static readonly não pode ser usado como um valor ref ou out (exceto em um construtor estático)
  • CS1605: não é possível usar a variável como um valor ref ou out porque ela é somente leitura
  • CS1649: os membros de um campo readonly não podem ser usados como um valor ref ou out (exceto em um construtor)
  • CS1651: campos de um campo static readonly não podem ser usados como um valor ref ou out (exceto em um construtor estático)
  • CS1655: não é possível usar campos do tipo como um valor ref ou out
  • CS1657: não é possível usar variável como um valor ref ou out
  • CS8329: não é possível usar a variável como um valor ref ou out porque ela é uma variável somente leitura
  • CS8330: os membros da variável não podem ser usados como um valor ref ou out porque é uma variável somente leitura
  • CS8331: não é possível atribuir à variável ou usá-la como o lado direito de uma atribuição ref porque ela é uma variável somente leitura
  • CS8332: não é possível atribuir a um membro da variável ou usá-la como o lado direito de uma atribuição ref porque ela é uma variável somente leitura

Exemplos de variáveis que não são graváveis incluem:

  • Campos readonly, tanto campos de instância quanto campos estáticos.
  • Membros de campos readonly.
  • A variável this.
  • A variável de iteração foreach
  • Uma variável de uso ou uma variável fixa.

Você deve copiar o valor e passar uma referência para a cópia.

Violações de segurança de referência

O compilador controla o contexto seguro de referenciais e variáveis de referência. O compilador emite erros ou avisos em código não seguro, quando uma variável de referência se refere a uma variável referencial que não é mais válida. O referencial deve ter um contexto seguro que seja pelo menos tão largo quanto o contexto de segurança de referência da variável de referência. Violar essas verificações de segurança significa que a variável de referência acessa a memória aleatória em vez da variável referencial.

  • CS8166: não é possível retornar um parâmetro por referência porque ele não é um parâmetro ref
  • CS8167: não é possível retornar por referência um membro do parâmetro porque ele não é um parâmetro ref ou out
  • CS8168: não é possível retornar o local por referência porque não é um local de referência
  • CS8169: não é possível retornar um membro da variável local por referência porque ele não é um local de referência
  • CS8345: a propriedade de campo ou implementada automaticamente não pode ser do tipo, a menos que seja um membro de instância de um ref struct.
  • CS8351: branches de um operador condicional ref não podem se referir a variáveis com escopos de declaração incompatíveis
  • CS8374: não é possível referência, a origem tem um escopo de escape mais estreito do que o destino.
  • CS9077: não é possível retornar um parâmetro por referência por meio de um parâmetro ref; ele só pode ser retornado em uma instrução return
  • CS9078: não é possível retornar por referência um membro do parâmetro por meio de um parâmetro ref; ele só pode ser retornado em uma instrução return
  • CS9079: não é possível atribuir novamente a origem ao destino porque a origem só pode escapar do método atual por meio de uma instrução de retorno.
  • CS9096: não é possível atribuir novamente a origem ao destino porque a origem tem um escopo de escape de valor mais amplo do que o destino, o que permite a atribuição por meio de destino de valores com escopos de escape mais estreitos do que a origem.

Avisos:

  • CS9085: essa referência atribui a origem ao destino, mas a origem tem um escopo de escape mais estreito do que o destino.
  • CS9086: os branches do operador condicional de referência referem-se a variáveis com escopos de declaração incompatíveis
  • CS9087: isso retorna um parâmetro por referência, mas não é um parâmetro ref
  • CS9089: isso retorna por referência um membro do parâmetro que não é um parâmetro ref ou out
  • CS9091: isso retorna o local por referência, mas não é uma referência local
  • CS9092: isso retorna um membro do local por referência, mas não é uma referência local
  • CS9093: essa referência atribui a origem ao destino, mas a origem só pode escapar do método atual por meio de uma instrução de retorno.
  • CS9094: isso retorna um parâmetro por referência por meio de um parâmetro ref; mas ele só pode ser retornado com segurança em uma instrução return
  • CS9095: isso retorna por referência um membro do parâmetro por meio de um parâmetro ref; mas ele só pode ser retornado com segurança em uma instrução return
  • CS9097: essa referência atribui a origem ao destino, mas a origem tem um escopo de escape de valor mais amplo do que o destino, permitindo a atribuição por meio de destino de valores com escopos de escape mais estreitos do que a origem.

O compilador usa a análise estática para determinar se o referencial é válido em todos os pontos em que a variável de referência pode ser usada. Você precisa refatorar o código para que o referencial permaneça válido em todos os locais em que a variável de referência possa se referir a ele. Para obter detalhes sobre as regras de segurança de referência, confira o padrão C# em contextos de segurança de referência.