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

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. De hoofdtekst van de methode kan worden 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 gedefinieerde operator == 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.