Delen via


C# Waarschuwingsgolven

Nieuwe waarschuwingen en fouten kunnen worden geïntroduceerd in elke release van de C#-compiler. Wanneer nieuwe waarschuwingen op bestaande code kunnen worden gerapporteerd, worden deze waarschuwingen geïntroduceerd onder een opt-in-systeem dat wordt aangeduid als een waarschuwingsgolf. Het opt-in-systeem betekent dat u geen nieuwe waarschuwingen voor bestaande code moet zien zonder actie te ondernemen om ze in te schakelen. Waarschuwingsgolven worden ingeschakeld met behulp van het element AnalysisLevel in uw projectbestand. Wanneer <TreatWarningsAsErrors>true</TreatWarningsAsErrors> is opgegeven, genereren waarschuwingen voor waarschuwingsgolf inschakelen fouten. Waarschuwingsgolf 5 diagnostische gegevens zijn toegevoegd in C# 9. Waarschuwingsgolf 6 diagnostische gegevens zijn toegevoegd in C# 10. Waarschuwingsgolf 7 diagnostische gegevens zijn toegevoegd in C# 11. Waarschuwingsgolf 8 diagnostische gegevens zijn toegevoegd in C# 12.

CS9123 - Het adres van lokale of parameter in asynchrone methode kan een GC-gat maken.

Waarschuwingsgolf 8

De & operator mag niet worden gebruikt voor parameters of lokale variabelen in asynchrone methoden. De volgende code produceert CS9123:

public static async Task LogValue()
{
    int x = 1;
    unsafe {
        int* y = &x;
        Console.WriteLine(*y);
    }
    await Task.Delay(1000);
}

Vanaf C# 13 genereert deze code een compilerfout.

CS8981 - De typenaam bevat alleen kleine ascii-tekens.

Waarschuwingsgolf 7

Nieuwe trefwoorden die worden toegevoegd voor C# zijn allemaal kleine ASCII-tekens. Deze waarschuwing zorgt ervoor dat geen van uw typen conflicteert met toekomstige trefwoorden. De volgende code produceert CS8981:

public class lowercasename
{
}

U kunt deze waarschuwing oplossen door de naam van het type te wijzigen zodat er ten minste één niet-kleine ASCII-teken is opgenomen, zoals een hoofdletter, een cijfer of een onderstrepingsteken.

CS8826 - Gedeeltelijke methodedeclaraties hebben handtekeningverschillen.

Waarschuwingsgolf 6

Deze waarschuwing corrigeert enkele inconsistenties bij het rapporteren van verschillen tussen gedeeltelijke methodehandtekeningen. De compiler heeft altijd een fout gerapporteerd wanneer de handtekeningen van de gedeeltelijke methode verschillende CLR-handtekeningen hebben gemaakt. Nu rapporteert de compiler CS8826 wanneer de handtekeningen syntactisch verschillend zijn in C#. Houd rekening met de volgende gedeeltelijke klasse:

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);
}

De volgende gedeeltelijke klasse-implementatie genereert verschillende voorbeelden van 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) { }
}

Notitie

Als voor de implementatie van een methode een niet-null-referentietype wordt gebruikt wanneer de andere declaratie nullable-verwijzingstypen accepteert, wordt CS8611 gegenereerd in plaats van CS8826.

Als u een exemplaar van deze waarschuwingen wilt oplossen, moet u ervoor zorgen dat de twee handtekeningen overeenkomen.

CS7023 - Een statisch type wordt gebruikt in een 'is' of 'as'-expressie.

Waarschuwingsgolf 5

De is expressies worden as altijd geretourneerd false voor een statisch type, omdat u geen exemplaren van een statisch type kunt maken. De volgende code produceert 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");
    }
}

De compiler rapporteert deze waarschuwing omdat de typetest nooit kan slagen. Als u deze waarschuwing wilt corrigeren, verwijdert u de test en verwijdert u alle code die alleen wordt uitgevoerd als de test is geslaagd. In het voorgaande voorbeeld wordt de else component altijd uitgevoerd. U kunt die methodetekst vervangen door die ene regel:

Console.WriteLine("o is not an instance of a static class");

CS8073 - Het resultaat van de expressie is altijd 'false' (of 'true').

Waarschuwingsgolf 5

De operatoren != retourneren false altijd (oftrue) wanneer een instantie van een struct type wordt vergeleken met null.== In de volgende code ziet u deze waarschuwing. Stel dat S dit een struct definitie operator == is en 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...
}

Als u deze fout wilt oplossen, verwijdert u de null-controle en code die zou worden uitgevoerd als het object is null.

CS8848 - Operator 'van' kan hier niet worden gebruikt vanwege prioriteit. Gebruik haakjes om ondubbelzinnig te zijn.

Waarschuwingsgolf 5

In de volgende voorbeelden ziet u deze waarschuwing. De expressie bindt onjuist vanwege de prioriteit van de operators.

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];

Als u deze fout wilt oplossen, plaatst u haakjes rond de query-expressie:

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)];

Leden moeten volledig zijn toegewezen. Gebruik van niet-toegewezen variabele (CS8880, CS8881, CS8882, CS8883, CS8884, CS8885, CS8886, CS8887)

Waarschuwingsgolf 5

Verschillende waarschuwingen verbeteren de definitieve toewijzingsanalyse voor struct typen die zijn gedeclareerd in geïmporteerde assembly's. Al deze nieuwe waarschuwingen worden gegenereerd wanneer een struct in een geïmporteerde assembly een niet-toegankelijk veld (meestal een private veld) van een verwijzingstype bevat, zoals wordt weergegeven in het volgende voorbeeld:

public struct Struct
{
    private string data = String.Empty;
    public Struct() { }
}

In de volgende voorbeelden ziet u de waarschuwingen die zijn gegenereerd op basis van de verbeterde analyse van definitieve toewijzingen:

  • CS8880: Eigenschap automatisch geïmplementeerd moet volledig worden toegewezen voordat het besturingselement wordt geretourneerd aan de aanroeper.
  • CS8881: Veld 'veld' moet volledig worden toegewezen voordat het besturingselement wordt geretourneerd aan de beller.
  • CS8882: De outparameter 'parameter' moet worden toegewezen voordat het besturingselement de huidige methode verlaat.
  • CS8883: Gebruik van mogelijk niet-toegewezen automatisch geïmplementeerde eigenschap 'Eigenschap'.
  • CS8884: Gebruik van mogelijk niet-toegewezen veld 'Veld'
  • CS8885: Het object 'this' kan niet worden gebruikt voordat alle velden zijn toegewezen.
  • CS8886: Gebruik van niet-toegewezen uitvoerparameter 'parameterName'.
  • CS8887: Gebruik van niet-toegewezen lokale variabele '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;
    }
}

U kunt een van deze waarschuwingen oplossen door de geïmporteerde struct te initialiseren of toe te wijzen aan de standaardwaarde:

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 - Methode wordt niet gebruikt als invoerpunt omdat er een synchrone ingangspunt 'methode' is gevonden.

Waarschuwingsgolf 5

Deze waarschuwing wordt gegenereerd voor alle kandidaten voor asynchrone toegangspunten wanneer u meerdere geldige toegangspunten hebt, inclusief een of meer synchrone toegangspunten.

In het volgende voorbeeld wordt CS8892 gegenereerd:

public static void Main()
{
    RunProgram();
}

// CS8892
public static async Task Main(string[] args)
{
    await RunProgramAsync();
}

Notitie

De compiler gebruikt altijd het synchrone toegangspunt. Als er meerdere synchrone toegangspunten zijn, krijgt u een compilerfout.

Als u deze waarschuwing wilt oplossen, verwijdert of wijzigt u de naam van het asynchrone toegangspunt.

CS8897 - Statische typen kunnen niet worden gebruikt als parameters

Waarschuwingsgolf 5

Leden van een interface kunnen geen parameters declareren waarvan het type een statische klasse is. De volgende code laat zowel CS88897 als CS8898 zien:

public static class Utilities
{
    // elided
}

public interface IUtility
{
    // CS8897
    public void SetUtility(Utilities u);

    // CS8898
    public Utilities GetUtility();
}

Als u deze waarschuwing wilt oplossen, wijzigt u het parametertype of verwijdert u de methode.

CS8898 - statische typen kunnen niet worden gebruikt als retourtypen

Waarschuwingsgolf 5

Leden van een interface kunnen geen retourtype declareren dat een statische klasse is. De volgende code laat zowel CS88897 als CS8898 zien:

public static class Utilities
{
    // elided
}

public interface IUtility
{
    // CS8897
    public void SetUtility(Utilities u);

    // CS8898
    public Utilities GetUtility();
}

Als u deze waarschuwing wilt oplossen, wijzigt u het retourtype of verwijdert u de methode.