Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Novos avisos e erros podem ser apresentados em cada versão do compilador do C#. Quando novos avisos puderem ser relatados sobre o código existente, esses avisos serão apresentados em um sistema de aceitação chamado de ciclo de aviso. O sistema de opt-in significa que você não verá novos alertas no código existente sem tomar medidas para habilitá-los. Quando <TreatWarningsAsErrors>true</TreatWarningsAsErrors> é especificado, o ciclo de aviso habilitado gera erros. Os diagnósticos do ciclo de aviso 5 foram adicionados no C# 9. Os diagnósticos da onda de aviso 6 foram adicionados no C# 10. Os diagnósticos da onda de aviso 7 foram adicionados no C# 11. Os diagnósticos da onda de aviso 8 foram adicionados no C# 12. Os diagnósticos do ciclo de aviso 9 foram adicionados no C# 13. Os diagnósticos do ciclo de aviso 10 foram adicionados no C# 14.
Começando com o SDK do .NET 7 (C# 11), o sistema de build define ondas de aviso com as seguintes regras:
- AnalysisLevel rastreia o TFM atual se não for especificado.
- AnalysisLevel é definido como "latest" se o TFM atual for o TFM "latest" (conforme definido por uma propriedade que precisamos atualizar).
- WarningLevel deve rastrear o TFM atual se não for especificado
- WarningLevel não deve substituir o valor fornecido pelo usuário
- WarningLevel deverá ser definido como 4 se o projeto for um projeto do .NET Framework
Para SDKs anteriores ao .NET 7, o AnalysisLevel sempre substituiu WarningLevel.
CS9265 – O campo nunca é atribuído novamente e sempre terá seu valor padrão
Onda de aviso 10
Um ref campo em um ref struct que nunca é atribuído novamente sempre tem seu valor padrão, que é uma referência nula. O código a seguir produz CS9265:
ref struct Container
{
// CS9265: Field 'value' is never ref-assigned to,
// and will always have its default value (null reference)
public ref int value;
}
Para resolver esse aviso, atribua novamente o campo em um inicializador de campo ou em todos os caminhos de código do construtor. Como alternativa, remova o ref modificador da declaração de campo se o campo não precisar ser uma referência.
CS9123 – O operador '&' não deve ser usado em parâmetros ou variáveis locais em métodos assíncronos
Onda de aviso 8
O operador & não deve ser usado em parâmetros ou variáveis locais em métodos assíncronos.
O seguinte código produz o CS9123:
public static async Task LogValue()
{
int x = 1;
unsafe {
int* y = &x;
Console.WriteLine(*y);
}
await Task.Delay(1000);
}
CS8981 – O nome do tipo contém apenas caracteres ASCII com letras minúsculas. Esses nomes podem se tornar reservados para o idioma.
Onda de alerta 7
As novas palavras-chave adicionadas para C# serão todos caracteres ASCII em letras minúsculas. Esse aviso garante que nenhum dos tipos entre em conflito com as futuras palavras-chave. O código a seguir produz o CS8981:
public class lowercasename
{
}
Você pode resolver esse aviso, renomeando o tipo para incluir pelo menos um caractere ASCII que não seja em letras minúsculas, como um caractere em letras maiúsculas, um dígito ou um sublinhado.
CS8826 – As declarações de método parcial têm diferenças de assinatura.
Onda de aviso 6
Este aviso corrige algumas inconsistências no relatório de diferenças entre assinaturas de método parcial. O compilador sempre relatou um erro quando as assinaturas de método parcial criaram assinaturas CLR diferentes. Agora, o compilador relata o CS8826 quando as assinaturas são sintaticamente diferentes do C#. Considere a classe parcial a seguir:
public partial class PartialType
{
public partial void M1(int x);
public partial T M2<T>(string s) where T : struct;
public partial void M3(string s);
public partial void M4(object o);
public partial void M5(dynamic o);
public partial void M6(string? s);
}
A implementação de classe parcial a seguir gera vários exemplos de CS8626:
public partial class PartialType
{
// Different parameter names:
public partial void M1(int y) { }
// Different type parameter names:
public partial TResult M2<TResult>(string s) where TResult : struct => default;
// Relaxed nullability
public partial void M3(string? s) { }
// Mixing object and dynamic
public partial void M4(dynamic o) { }
// Mixing object and dynamic
public partial void M5(object o) { }
// Note: This generates CS8611 (nullability mismatch) not CS8826
public partial void M6(string s) { }
}
Observação
Se a implementação de um método usa um tipo de referência não anulável, quando a outra declaração aceita tipos de referência anulável, o CS8611 será gerado em vez do CS8826.
Para corrigir esses avisos, verifique se as duas assinaturas correspondem.
CS7023 — O segundo operando de um operador "is" ou "as" não pode ser um tipo estático.
Onda de aviso 5
As expressões is e as sempre retornam false para um tipo estático, pois não é possível criar instâncias de um tipo estático. O código a seguir produz o CS7023:
static class StaticClass
{
public static void Thing() { }
}
void M(object o)
{
// warning: cannot use a static type in 'is' or 'as'
if (o is StaticClass)
{
Console.WriteLine("Can't happen");
}
else
{
Console.WriteLine("o is not an instance of a static class");
}
}
O compilador relata esse aviso porque o teste de tipo nunca pode ter êxito. Para corrigir esse aviso, remova o teste e remova os códigos executados somente se o teste tiver êxito. No exemplo anterior, a cláusula else sempre é executada. Você substituir esse corpo do método por essa única linha:
Console.WriteLine("o is not an instance of a static class");
CS8073 – O resultado da expressão é sempre 'value', pois um valor do tipo 'type' nunca é igual a 'null' do tipo 'type'
Onda de aviso 5
Os operadores == e != sempre retornam false (ou true), ao comparar uma instância de um tipo struct com o null. O código a seguir demonstra esse aviso. Suponha que S é um struct que define operator == e operator !=:
class Program
{
public static void M(S s)
{
if (s == null) { } // CS8073: The result of the expression is always 'false'
if (s != null) { } // CS8073: The result of the expression is always 'true'
}
}
struct S
{
public static bool operator ==(S s1, S s2) => s1.Equals(s2);
public static bool operator !=(S s1, S s2) => !s1.Equals(s2);
public override bool Equals(object? other)
{
// Implementation elided
return false;
}
public override int GetHashCode() => 0;
// Other details elided...
}
Para corrigir esse erro, remova a verificação nula e o código que seriam executados se o objeto fosse null.
CS8848 – O operador 'from' não pode ser usado aqui devido à precedência. Use parênteses para evitar ambiguidade.
Alerta de onda 5
Os exemplos a seguir demonstram esse aviso. A expressão é vinculada incorretamente devido à precedência dos operadores.
bool b = true;
var source = new Src();
b = true;
source = new Src();
var a = b && from c in source select c;
Console.WriteLine(a);
var indexes = new Src2();
int[] array = { 1, 2, 3, 4, 5, 6, 7 };
var range = array[0..from c in indexes select c];
Para corrigir esse erro, coloque a expressão de consulta entre parênteses:
bool b = true;
var source = new Src();
b = true;
source = new Src();
var a = b && (from c in source select c);
Console.WriteLine(a);
var indexes = new Src2();
int[] array = { 1, 2, 3, 4, 5, 6, 7 };
var range = array[0..(from c in indexes select c)];
Os membros devem ser totalmente designados. Uso de variável não atribuída (CS8880, CS8881, CS8882, CS8883, CS8884, CS8885, CS8886, CS8887)
Onda de alerta 5
Vários avisos melhoram a análise de atribuição definitiva para os tipos struct declarados em assemblies importados. Todos esses novos avisos são gerados quando uma estrutura em um assembly que foi importado inclui um campo inacessível (geralmente um campo private) de um tipo de referência, conforme mostrado no exemplo a seguir.
public struct Struct
{
private string data = String.Empty;
public Struct() { }
}
Os exemplos a seguir mostram os avisos gerados com base na análise de atribuição definitiva aprimorada:
- CS8880: a propriedade autoimplementada 'Property' precisa ser totalmente atribuída, antes que o controle seja retornado ao chamador. Considere atualizar para a versão de linguagem "version" para definir automaticamente o valor padrão da propriedade.
- CS8881: o campo 'field' deve estar completamente atribuído antes que o controle seja retornado ao chamador. Considere atualizar para a versão de linguagem "version" para definir automaticamente o valor padrão do campo.
- CS8882: O parâmetro
out"parameter" deve ser atribuído antes que o controle saia do método atual. - CS8883: uso da propriedade autoimplementada possivelmente não atribuída 'Property'.
- CS8884: uso do campo possivelmente não atribuído 'Field'
- CS8885: O objeto 'this' não pode ser usado antes de todos os campos serem atribuídos. Considere atualizar para a versão de idioma 'version' para definir automaticamente os valores padrão dos campos não atribuídos.
- CS8886: uso do parâmetro "parameterName" não atribuído.
- CS8887: uso da variável local não atribuída 'variableName'
public struct DefiniteAssignmentWarnings
{
// CS8880
public Struct Property { get; }
// CS8881
private Struct field;
// CS8882
public void Method(out Struct s)
{
}
public DefiniteAssignmentWarnings(int dummy)
{
// CS8883
Struct v2 = Property;
// CS8884
Struct v3 = field;
// CS8885:
DefiniteAssignmentWarnings p2 = this;
}
public static void Method2(out Struct s1)
{
// CS8886
var s2 = s1;
s1 = default;
}
public static void UseLocalStruct()
{
Struct r1;
var r2 = r1;
}
}
Você pode corrigir qualquer um desses avisos, inicializando ou atribuindo o struct importado ao valor padrão:
public struct DefiniteAssignmentNoWarnings
{
// CS8880
public Struct Property { get; } = default;
// CS8881
private Struct field = default;
// CS8882
public void Method(out Struct s)
{
s = default;
}
public DefiniteAssignmentNoWarnings(int dummy)
{
// CS8883
Struct v2 = Property;
// CS8884
Struct v3 = field;
// CS8885:
DefiniteAssignmentNoWarnings p2 = this;
}
public static void Method2(out Struct s1)
{
// CS8886
s1 = default;
var s2 = s1;
}
public static void UseLocalStruct()
{
Struct r1 = default;
var r2 = r1;
}
}
CS8892 – O método não será usado como ponto de entrada, pois o ponto de entrada síncrono 'method' foi encontrado.
Onda de aviso 5
Esse aviso é gerado em todos os candidatos de ponto de entrada assíncrono, quando você tem vários pontos de entrada válidos, incluindo um ou mais pontos de entrada síncronos.
O seguinte exemplo gera o erro CS8892:
public static void Main()
{
RunProgram();
}
// CS8892
public static async Task Main(string[] args)
{
await RunProgramAsync();
}
Observação
O compilador sempre usa o ponto de entrada síncrono. Caso haja vários pontos de entrada síncronos, você receberá um erro do compilador.
Para corrigir esse aviso, remova ou renomeie o ponto de entrada assíncrono.
CS8897 – tipos estáticos não podem ser usados como parâmetros
Onda de aviso 5
Os membros de uma interface não podem declarar parâmetros cujo tipo é uma classe estática. O código a seguir demonstra CS8897 e CS8898:
public static class Utilities
{
// elided
}
public interface IUtility
{
// CS8897
public void SetUtility(Utilities u);
// CS8898
public Utilities GetUtility();
}
Para corrigir esse aviso, altere o tipo de parâmetro ou remova o método.
CS8898 – tipos estáticos não podem ser usados como tipos de retorno
Onda de aviso 5
Os membros de uma interface não podem declarar um tipo de retorno que seja uma classe estática. O código a seguir demonstra CS8897 e CS8898:
public static class Utilities
{
// elided
}
public interface IUtility
{
// CS8897
public void SetUtility(Utilities u);
// CS8898
public Utilities GetUtility();
}
Para corrigir esse aviso, altere o tipo de retorno ou remova o método.