Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Os seguintes erros podem ser gerados quando você está trabalhando com variáveis de referência:
-
CS0192: Um
readonlycampo não pode ser usado como umrefououtvalor (exceto em um construtor) -
CS0199: Um
static readonlycampo não pode ser usado como umrefououtvalor (exceto em um construtor estático) -
CS0206: Uma propriedade ou um indexador que não devolva uma referência ref não podem ser usados como um valor
outouref -
CS0631:
refeoutnão são válidos neste contexto -
CS0767: Não é possível herdar a interface com os parâmetros de tipo especificados porque faz com que o método contenha sobrecargas que diferem apenas em
refeout -
CS1510: Um
refououtvalor deve ser uma variável atribuível -
CS1605: Não é possível usar a variável como valor de um
refououtporque é apenas de leitura -
CS1623: Os iteradores não podem ter
ref,inououtparâmetros -
CS1649: Membros de um
readonlycampo não podem ser usados como umrefououtvalor (exceto em um construtor) -
CS1651: Os campos de um campo estático só de leitura não podem ser usados como valor de
refouout(exceto num construtor estático) -
CS1655: Não é possível usar campos do tipo como um
refououtvalor -
CS1657: Não é possível usar variável como um
refououtvalor -
CS1741: Um
refououtparâmetro não pode ter um valor padrão -
CS1939: Não é possível passar a variável de intervalo como um
outourefparâmetro -
CS1988: Os métodos assíncronos não podem ter parâmetros
ref,inouout -
CS7084: Um evento do Windows Runtime não pode ser passado como parâmetro
outouref. - CS8196: A 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 contenha umrefoperador condicional - CS8326: Ambos os valores de operador condicional devem ser valores ref ou nenhum pode ser um valor ref
- CS8327: A expressão deve ser do tipo correto para corresponder ao valor ref alternativo
-
CS8329: Não é possível usar a variável como um
refououtvalor porque é uma variável somente leitura -
CS8330: Os membros de uma variável não podem ser utilizados como valor
refououtporque é uma variável só de leitura -
CS8331: Não é possível atribuir à variável nem usá-la como o lado direito de uma atribuição
refporque é uma variável só de leitura -
CS8332: Não é possível atribuir a um membro de uma variável nem utilizá-lo como o lado direito de uma
refatribuição, porque é uma variável só de 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 a 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). -
CS8373: O lado esquerdo de uma
refatribuição deve ser uma variável ref. -
CS8388: Uma
outvariável não pode ser declarada como uma ref local -
CS8977: Não é possível usar '
ref', 'in', ou 'out' na assinatura de um método atribuído com 'UnmanagedCallersOnly'. - CS8986: O modificador 'visado' do parâmetro não corresponde ao alvo.
- CS8987: O modificador 'scoped' do parâmetro não corresponde ao membro sobrescrito ou implementado.
- CS9061: O modificador 'com escopo' não pode ser usado com descartar.
- CS9062: Tipos e pseudónimos não podem ser chamados de 'scoped'.
- CS9063: UnscopedRefAttribute não pode ser aplicado a este parâmetro porque, por defeito, não tem escopo.
- CS9065: Não use 'System.Runtime.CompilerServices.ScopedRefAttribute'. Use a palavra-chave 'scoped' em vez disso.
- CS9066: UnscopedRefAttribute não pode ser aplicado a parâmetros que tenham um modificador 'scoped'.
- CS9072: Uma variável de desconstrução não pode ser declarada como uma ref local
- CS9101: UnscopedRefAttribute só pode ser aplicado a métodos e propriedades de instância de structs ou de interfaces virtuais, e não pode ser aplicado a construtores ou membros exclusivos de inicialização.
- CS9102: UnscopedRefAttribute não pode ser aplicado a uma implementação de interface porque o membro implementado não tem esse atributo.
-
CS9104: Um
usingrecurso de instrução do tipo não pode ser usado em métodos assíncronos ou expressões lambda assíncronas. -
CS9190:
readonlymodificador deve ser especificado apósref. -
CS9199: Um
ref readonlyparâmetro não pode ter o atributo out.
Os seguintes avisos são gerados quando as variáveis de referência são usadas incorretamente:
- CS9073: O modificador 'visado' do parâmetro não corresponde ao alvo.
- CS9074: O modificador 'scoped' do parâmetro não corresponde ao membro substituído ou implementado.
-
CS9191: O
refmodificador para o argumento correspondente aoinparâmetro é equivalente ain. Considere usarinem vez disso. -
CS9192: Argumento deve ser passado com
refouinpalavra-chave. -
CS9193: Argumento deve ser uma variável porque é passado para um
ref readonlyparâmetro -
CS9195: Argumento deve ser passado com a
inpalavra-chave - 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
ref readonlyparâmetro, masref readonlydeve ser usado apenas para referências. Considere declarar o parâmetro comoin. - CS9201: O campo Ref deve ser atribuído a ref antes do uso.
- CS9265: O campo nunca recebe uma atribuição por referência e terá sempre o seu valor predefinido (referência nula)
Estes erros e avisos seguem estes temas:
- Sintaxe incorreta: a sintaxe da sua declaração ou uso é inválida.
-
Construções de linguagem onde
refas variáveis não são válidas: Algumas expressões idiomáticas do C# não permitem variáveis. Normalmente, isto acontece porque a análise de segurança de ref não pode ser realizada de forma fiável. - Expressão de valor usada onde uma variável de referência é necessária: A expressão usada como uma variável de referência deve ser uma variável, não uma expressão de valor.
- Variáveis de referência modificáveis que referem variáveis só de leitura: Uma referência a uma variável só de leitura não pode ser passada como referência modificável.
Este artigo usa o termo variável de referência como termo genérico para um parâmetro declarado com um dos modificadores in, ref readonly, ref ou out, ou uma variável local ref, um campo ref num ref struct ou um retorno ref. Uma variável de referência refere-se a outra variável, chamada referente.
Sintaxe incorreta
Esses erros indicam que você está usando sintaxe incorreta em relação às variáveis de referência:
-
CS8373: O lado esquerdo de uma atribuição
refdeve ser uma variável ref. -
CS8388: Uma
outvariável não pode ser declarada como uma ref local. -
CS9190:
readonlymodificador deve ser especificado apósref.
Para corrigir estes erros:
- Certifique-se de que o operando esquerdo de um
= refoperador seja uma variável de referência em lugar de uma expressão de valor ou um local não de referência. A atribuição de referências exige que ambos os lados sejam variáveis de referência capazes de criar um alias para o mesmo local de armazenamento (CS8373). - Ao declarar parâmetros de referência, escreva o modificador como
ref readonlyem vez dereadonly ref. A especificação da linguagem C# exige que arefpalavra-chave preceda oreadonlymodificador nas declarações de parâmetros para manter uma sintaxe consistente em todos os tipos de parâmetros de referência (CS9190). - Use a
refpalavra-chave em vez deoutquando declarar variáveis de referência locais.outé exclusivamente um modificador de parâmetro que indica que um método deve atribuir um valor antes de devolver, enquantorefé a palavra-chave apropriada para criar variáveis locais que apelidificam outras localizações de armazenamento (CS8388). Para mais informações sobre variáveis de referência e os seus requisitos de sintaxe, consulte variáveis de referência e a Especificação da Linguagem C#.
Restrições de variáveis de referência
Os seguintes erros indicam que uma variável de referência não pode ser usada onde você tem uma:
-
CS0631:
refeoutnão são válidos neste contexto -
CS0767: Não é possível herdar a interface com os parâmetros de tipo especificados porque faz com que o método contenha sobrecargas que diferem apenas em
refeout -
CS1623: Os iteradores não podem ter
ref,inououtparâmetros -
CS1741: Um
refououtparâmetro não pode ter um valor padrão -
CS1939: Não é possível passar a variável de intervalo como um
outourefparâmetro -
CS1988: Os métodos assíncronos não podem ter parâmetros
ref,inouout -
CS7084: Um evento do Windows Runtime não pode ser passado como um parâmetro
outouref. -
CS8196: A referência a uma variável digitada
outimplicitamente não é permitida na mesma lista de argumentos. -
CS8325: 'await' não pode ser usado em uma expressão que contenha um
refoperador condicional - CS8326: Ambos os valores de operador condicional devem ser valores ref ou nenhum pode ser um valor ref
- CS8327: A expressão deve ser do tipo correto para corresponder ao valor ref 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 a 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 ref local
-
CS9104: Um
usingrecurso de instrução do tipo não pode ser usado em métodos assíncronos ou expressões lambda assíncronas. -
CS9199: Um
ref readonlyparâmetro 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
ref readonlyparâmetro, masref readonlydeve ser usado apenas para referências. Considere declarar o parâmetro comoin. - CS9201: O campo ref deve ter uma atribuição ref antes de ser utilizado.
- CS9265: Ao campo nunca é atribuída uma referência e terá sempre o valor predefinido (referência nula)
Para corrigir estes erros:
- Remover parâmetros de referência dos indexadores. Os indexadores são concebidos para fornecer uma sintaxe de acesso semelhante a um array e o compilador não pode garantir um rastreio seguro ao longo da vida para referências passadas através de acessores indexadores (CS0631, CS1623).
- Remover parâmetros de referência dos métodos iteradores. Os iteradores executam código preguiçosamente através de múltiplas chamadas usando máquinas de estados, e o compilador não pode garantir que as variáveis referenciadas permanecem válidas através dos limites de yield return onde a execução é suspensa e retomada (CS1623).
- Remover parâmetros de referência dos métodos assíncronos. Métodos assíncronos podem suspender a execução em pontos de espera e retomar em diferentes threads, tornando impossível garantir que as variáveis referenciadas permaneçam válidas e acessíveis durante toda a execução do método (CS1988).
- Evite usar expressões await dentro das expressões condicionais ref. A operação await pode suspender a execução e invalidar as referências selecionadas pelo operador condicional, levando à possível utilização de referências invalidadas quando a execução for retomada (CS8325).
- Assegure que ambos os ramos de um operador condicional ref retornem referências ou nenhum retorne uma referência, e quando ambos são referências, estas devem ser do mesmo tipo. O operador condicional deve produzir um tipo de resultado consistente que possa ser usado em segurança pelo código de chamada, independentemente do ramo selecionado (CS8326, CS8327).
- Remova os valores predefinidos dos
refparâmetros eout. Os parâmetros de referência devem ser sempre fornecidos no local da chamada para estabelecer a relação de aliasing necessária entre o parâmetro e uma variável existente, tornando os valores padrão semanticamente sem significado (CS1741). - Evite declarar uma variável tipada
outimplicitamente numa lista de argumentos que também faça referência a essa mesma variável. O compilador deve inferir o tipo da variável a partir da assinatura do método enquanto valida simultaneamente os usos dessa variável dentro da mesma expressão, criando uma dependência circular (CS8196). - Não passe variáveis de intervalo de consulta LINQ como parâmetros de referência. As variáveis de intervalo são variáveis de iteração geradas pelo compilador cujo tempo de vida é gerido pelo modelo de execução da consulta e não possuem localizações de memória estáveis que possam ser referenciadas em segurança (CS1939).
- Use variáveis de valor normais em vez de referências locais ao desconstruir objetos. A desconstrução cria novas variáveis para receber os valores desconstruídos e as variáveis de referência tentariam usar um alias destes valores temporários em vez de os armazenar independentemente (CS9072).
- Evite implementar múltiplas interfaces onde os métodos diferem apenas pelos modificadores
refeoutnos parâmetros. A especificação da linguagem C# trata estas como assinaturas distintas, mas não fornece uma forma de desambiguar qual implementação chamar, uma vez que ambosrefpartilhamouta mesma sintaxe de chamada nos limites da implementação (CS0767). - Remover parâmetros de referência dos métodos decorados com System.Runtime.InteropServices.UnmanagedCallersOnlyAttribute. Estes métodos podem ser chamados a partir de código não gerido que não compreende as regras de segurança de referência do C# e não garante uma gestão adequada ao longo da vida útil das variáveis referenciadas através do limite gerido/não gerido (CS8977).
- Use o
refmodificador no primeiro parâmetro do método de extensão apenas para tipos de valor ou tipos genéricos restritos a tipos de valor. Os tipos de referência já são passados por referência ao nível do CLR e a adiçãorefcriaria uma referência para uma referência, enquanto extensões de tipo de valor comrefpossibilitam a mutação da instância estendida (CS8337, CS8338). - Não passe eventos de Runtime do Windows como parâmetros de referência. Estes eventos seguem o sistema de tipos Windows Runtime, que tem uma duração de vida e semântica de threading diferente das referências .NET e não suporta o comportamento de aliasing exigido pelos parâmetros de referência C# (CS7084).
- Remova o System.Runtime.InteropServices.OutAttribute dos parâmetros
ref readonly. Este atributo foi concebido para organizar semântica em cenários de invocação de plataforma onde a direção do parâmetro é apenas de saída, o que entra em conflito comref readonlya garantia de que o parâmetro faz referência a dados existentes que não serão reatribuídos (CS9199). - Assegure que todos
refos campos de um tipo são atribuídos quer nos inicializadores de campo, quer em todos os caminhos do código do construtor, antes de o construtor ser concluído. Campos ref não inicializados conteriam referências inválidas que poderiam levar à corrupção da memória se acedidas (CS9201, CS9265). - Compare os modificadores de tipo de referência (
ref,in,out,ref readonly) entre um método e o seu método base sobreposto ou método de interface implementado. O modificador de referência faz parte do contrato de assinatura do método que os tipos derivados devem respeitar para manter a substituibilidade e as expectativas do chamador (CS9196, CS9197, CS9198). - Declare parâmetros como
inem vez deref readonlyquando fornecer valores por defeito.ref readonlyé concebido para cenários em que o chamador passa uma referência a uma variável existente, enquantoinos parâmetros podem aceitar tanto referências como cópias temporárias de valores, tornando os valores padrão significativos (CS9200).
Para mais informações sobre onde as variáveis de referência são permitidas, veja Parâmetros de método, Iteradores, Padrões de programação assíncrona e a Especificação da Linguagem C#.
unscoped ref Restrições
O qualificador unscoped nos parâmetros ref não é permitido em alguns contextos:
- CS9101: UnscopedRefAttribute só pode ser aplicado a métodos e propriedades de instância de struct ou interface virtual, e não pode ser aplicado a construtores ou membros apenas de init.
- CS9102: UnscopedRefAttribute não pode ser aplicado a uma implementação de interface porque o membro implementado não tem este atributo.
Para corrigir estes erros:
- Remova o
unscopedmodificador ou o System.Diagnostics.CodeAnalysis.UnscopedRefAttribute atributo dos construtores struct e dos membros apenas de init. Estes membros têm uma semântica especial de inicialização onde o compilador deve garantir que quaisquer referências não persistam além da fase de inicialização, e a permissão de referências sem âmbito violaria a garantia de que a inicialização se conclui antes de a estrutura se tornar totalmente acessível (CS9101). - Remova o
unscopedmodificador dos métodos de implementação de interface quando o método correspondente não o tem. A característica sem escopo afeta o contrato do método no que diz respeito às garantias de duração das referências, e as implementações devem manter o mesmo contrato da interface que estão a implementar para garantir que os chamadores possam confiar num comportamento de duração consistente, independentemente da implementação invocada (CS9102).
Para mais informações sobre referências com e sem escopo, veja Parâmetros de Método e Restrição de contexto seguro na especificação da linguagem C#.
As variáveis de referência requerem um referente
Você deve fornecer uma variável como argumento para um parâmetro de referência, retorno de referência ou atribuição local de referência:
-
CS0206: Uma propriedade ou indexador que não devolve por ref não pode ser utilizado como um valor
outouref -
CS1510: Um
refououtvalor deve ser uma variável atribuível
Advertências:
-
CS9191: O
refmodificador para o argumento correspondente aoinparâmetro é equivalente ain. Considere usarinem vez disso. -
CS9192: Argumento deve ser passado com
refouinpalavra-chave. -
CS9193: Argumento deve ser uma variável porque é passado para um
ref readonlyparâmetro -
CS9195: Argumento deve ser passado com a
inpalavra-chave
Para corrigir estes erros:
- Armazene o resultado de um acesso a propriedade ou indexador numa variável local antes de a passar como parâmetro de referência. Propriedades e indexadores são métodos que retornam valores em vez de fornecer acesso direto a locais de armazenamento, e os parâmetros de referência requerem uma variável real com uma localização de memória estável que possa ser aliasada (CS0206, CS1510).
- Use o
inmodificador em vez derefao passar argumentos parainparâmetros. Emborareftecnicamente funcione devido à compatibilidade retroativa, oinmodificador expressa de forma mais clara a intenção de que o argumento é apenas de leitura e pode ser passado de forma mais eficiente como referência sem copiar (CS9191, CS9195). - Adicione o modificador de referência apropriado (
ref,in, ouref readonly) ao passar argumentos para parâmetros que esperam referências. Omitir o modificador pode fazer com que o compilador crie uma cópia temporária do valor, o que é ineficiente e pode levar a comportamentos inesperados se o código de chamada esperar que as modificações sejam refletidas na variável original (CS9192, CS9193).
Para mais informações sobre parâmetros de referência e passagem de variáveis por referência, consulte Parâmetros de método, palavra-chave ref e a Especificação da Linguagem C#.
Variáveis de referência graváveis requerem um referente gravável
Uma variável de referência gravável requer que o referente também seja gravável. Os seguintes erros indicam que a variável não é gravável:
-
CS0192: Um
readonlycampo não pode ser usado como umrefououtvalor (exceto em um construtor) -
CS0199: Um
static readonlycampo não pode ser usado como umrefououtvalor (exceto em um construtor estático) -
CS1605: Não é possível usar variável como um
refououtvalor porque é somente leitura -
CS1649: Membros de um
readonlycampo não podem ser usados como umrefououtvalor (exceto em um construtor) -
CS1651: Campos de um
static readonlycampo não podem ser usados como umrefououtvalor (exceto em um construtor estático) -
CS1655: Não é possível usar campos do tipo como um
refououtvalor -
CS1657: Não é possível usar variável como um
refououtvalor -
CS8329: Não é possível usar a variável como um
refououtvalor porque é uma variável somente leitura -
CS8330: Os membros da variável não podem ser usados como valor
refououtporque é uma variável apenas de leitura -
CS8331: Não é possível atribuir à variável nem usá-la como o lado direito de uma atribuição
ref, porque é uma variável só de leitura -
CS8332: Não é possível atribuir a um membro de uma variável nem utilizá-lo como lado direito de uma
refoperação de atribuição, porque é uma variável só de leitura
Para corrigir estes erros:
- Copie o valor de um campo só de leitura para uma variável local e passe a variável local como um parâmetro
refouout. Campos apenas de leitura são imutáveis após a inicialização (exceto dentro dos construtores) e permitir referências graváveis a eles violaria a garantia de imutabilidade que apenas leitura fornece (CS0192, CS0199,CS1649, CS1651). - Use
ref readonlyouinparâmetros em vez derefououtquando precisar de passar variáveis apenas de leitura, variáveis de iteração ou outros valores não graváveis por referência. Estes modificadores indicam que o método só lê o valor referenciado sem tentar modificá-lo. Isso está alinhado com as restrições de imutabilidade da variável original (CS1605,CS1655,CS1657, CS8329). - Copie os membros das variáveis de somente leitura para variáveis locais antes de serem passadas como referências graváveis. Embora o próprio membro possa não ser declarado como somente leitura, ele é acedido através de um caminho de somente leitura (via um campo de somente leitura, um parâmetro de
insomente leitura ou uma variável local deref readonlysomente leitura), e o compilador impõe a transitividade do estado de somente leitura para evitar mutações indiretas dos dados em somente leitura (CS8330, CS8332). - Evite atribuições de ref graváveis a variáveis apenas de leitura, variáveis de iteração foreach, usar recursos de instrução ou variáveis fixas de instruções. Estas variáveis têm semântica de vida especial gerida pelo compilador. A variável é automaticamente finalizada ou descartada no final do seu âmbito. Referências externas criam referências pendentes após a eliminação (CS8331).
Para mais informações sobre semântica de somente leitura e parâmetros de referência, consulte a palavra-chave readonly, o modificador de parâmetro in, o ref readonly e a Especificação da Linguagem C#.