Megosztás a következőn keresztül:


C# Figyelmeztető hullámok

A C#-fordító minden egyes kiadásában új figyelmeztetések és hibák jelennek meg. Ha új figyelmeztetések jelenthetők meg a meglévő kódon, ezeket a figyelmeztetéseket egy figyelmeztető hullámnak nevezett opt-in rendszerben vezetik be. A bejelentkezési rendszer azt jelenti, hogy nem szabad új figyelmeztetéseket látnia a meglévő kódon anélkül, hogy lépéseket kellene tennie az engedélyezésük érdekében. A figyelmeztető hullámok a projektfájl AnalysisLevel elemével engedélyezve vannak. Ha <TreatWarningsAsErrors>true</TreatWarningsAsErrors> meg van adva, az engedélyezett figyelmeztetőhullám-figyelmeztetések hibákat okoznak. Az 5. figyelmeztető hullám diagnosztikái a C# 9-ben lettek hozzáadva. A 6. figyelmeztető hullám diagnosztikái a C# 10-ben lettek hozzáadva. A 7. figyelmeztető hullám diagnosztikái a C# 11-ben lettek hozzáadva. A 8. figyelmeztető hullám diagnosztikái a C# 12-ben lettek hozzáadva.

CS9123 – A helyi vagy paraméter aszinkron metódusban való címének megadása GC-lyukat hozhat létre.

Figyelmeztető hullám 8

Az & operátor nem használható paramétereken vagy helyi változókon az aszinkron metódusokban. A következő kód állítja elő a CS9123-at:

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

A C# 13-tól kezdődően ez a kód fordítóhibát okoz.

CS8981 – A típusnév csak kisbetűs ascii karaktereket tartalmaz.

Figyelmeztető hullám 7

A C#-hoz hozzáadott új kulcsszavak mind kisbetűs ASCII-karakterek lesznek. Ez a figyelmeztetés biztosítja, hogy egyik típus sem ütközik a jövőbeli kulcsszavakkal. A következő kód állítja elő a CS8981-et:

public class lowercasename
{
}

Ezt a figyelmeztetést úgy kezelheti, ha átnevezi a típust, hogy legalább egy nem kisbetűs ASCII-karaktert( például nagybetűt, számjegyet vagy aláhúzásjelet) tartalmazzon.

CS8826 – A részleges metódusdeklarációk aláírási eltérésekkel rendelkeznek.

6. figyelmeztetési hullám

Ez a figyelmeztetés kijavít néhány inkonzisztenciát a részleges metódus-aláírások közötti jelentési különbségekben. A fordító mindig hibát jelentett, amikor a részleges metódus-aláírások különböző CLR-aláírásokat hoztak létre. A fordító most a CS8826-ot jelenti, ha az aláírások szintaktikailag eltérőek C#. Vegye figyelembe a következő részleges osztályt:

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

Az alábbi részleges osztály implementációja számos példát hoz létre a CS8626-ra:

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

Feljegyzés

Ha egy metódus megvalósítása nem null értékű hivatkozástípust használ, amikor a másik deklaráció null értékű hivatkozástípusokat fogad el, a CS8611 a CS8826 helyett jön létre.

A figyelmeztetések bármelyik példányának kijavításához győződjön meg arról, hogy a két aláírás egyezik.

CS7023 – Statikus típust használ egy "is" vagy "as" kifejezés.

5. figyelmeztetési hullám

A is kifejezések és as a kifejezések mindig statikus típushoz térnek vissza false , mert nem hozhatók létre statikus típusú példányok. A következő kód állítja elő a CS7023-at:

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

A fordító azért jelenti ezt a figyelmeztetést, mert a típusteszt soha nem lehet sikeres. A figyelmeztetés kijavításához távolítsa el a tesztet, és távolítsa el a végrehajtott kódot, ha a teszt sikeres volt. Az előző példában a else záradék mindig végrehajtásra kerül. A metódus törzsét a következő egyetlen sorra cserélheti:

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

CS8073 – A kifejezés eredménye mindig "hamis" (vagy igaz).

5. figyelmeztetési hullám

Az == és != az operátorok mindig visszaadják false (vagy true) a típuspéldányok struct nullösszehasonlítását. Az alábbi kód bemutatja ezt a figyelmeztetést. Tegyük felS, hogy a struct következőt definiáljaoperator ==: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...
}

A hiba kijavításához távolítsa el az objektum nullesetén végrehajtandó null ellenőrzést és kódot.

CS8848 – A "from" operátor nem használható itt az elsőbbség miatt. Zárójelek használatával egyértelműsíthet.

5. figyelmeztetési hullám

Az alábbi példák ezt a figyelmeztetést mutatják be. A kifejezés helytelenül kötődik az operátorok elsőbbsége miatt.

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

A hiba kijavításához zárójeleket helyezzen el a lekérdezési kifejezés körül:

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

A tagokat teljes mértékben ki kell osztani. Nem hozzárendelt változó használata (CS8880, CS8881, CS8882, CS8883, CS8884, CS8885, CS8886, CS8887)

5. figyelmeztetési hullám

Számos figyelmeztetés javítja az importált szerelvényekben deklarált típusok határozott hozzárendelési elemzését struct . Ezek az új figyelmeztetések akkor jönnek létre, ha egy importált szerelvény egy szerkezetében egy hivatkozástípus elérhetetlen mezője (általában egy private mező) szerepel, ahogyan az alábbi példában látható:

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

Az alábbi példák a továbbfejlesztett határozott hozzárendelés-elemzésből származó figyelmeztetéseket mutatják be:

  • CS8880: Az automatikusan megvalósított "Tulajdonság" tulajdonságot teljes mértékben ki kell osztani, mielőtt a rendszer visszaadja a vezérlést a hívónak.
  • CS8881: A "mező" mezőt teljes mértékben ki kell osztani, mielőtt a vezérlő visszakerül a hívóhoz.
  • CS8882: A "paraméter" kimenő paramétert hozzá kell rendelni, mielőtt a vezérlő elhagyja az aktuális metódust.
  • CS8883: Valószínűleg nem hozzárendelt, automatikusan implementált "Tulajdonság" tulajdonság használata.
  • CS8884: A "Mező" esetleg nem hozzárendelt mező használata
  • CS8885: Az "ez" objektum nem használható az összes mező hozzárendelése előtt.
  • CS8886: A "parameterName" nem hozzárendelt kimeneti paraméter használata.
  • CS8887: A "variableName" nem hozzárendelt helyi változó használata
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;
    }
}

Ezen figyelmeztetések bármelyikét kijavíthatja, ha inicializálja vagy hozzárendeli az importált szerkezetet az alapértelmezett értékhez:

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 – A metódus nem használható belépési pontként, mert egy szinkron belépési pont "metódus" található.

5. figyelmeztetési hullám

Ez a figyelmeztetés akkor jön létre az összes aszinkron belépési pont jelöltjén, ha több érvényes belépési ponttal rendelkezik, beleértve egy vagy több szinkron belépési pontot is.

Az alábbi példa a CS8892-t hozza létre:

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

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

Feljegyzés

A fordító mindig a szinkron belépési pontot használja. Több szinkron belépési pont esetén fordítóhiba jelenik meg.

A figyelmeztetés kijavításához távolítsa el vagy nevezze át az aszinkron belépési pontot.

CS8897 – Statikus típusok nem használhatók paraméterekként

5. figyelmeztetési hullám

Az interfész tagjai nem deklarálhatnak olyan paramétereket, amelyek típusa statikus osztály. Az alábbi kód a CS8897-et és a CS8898-at is bemutatja:

public static class Utilities
{
    // elided
}

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

    // CS8898
    public Utilities GetUtility();
}

A figyelmeztetés kijavításához módosítsa a paraméter típusát, vagy távolítsa el a metódust.

CS8898 – A statikus típusok nem használhatók visszatérési típusokként

5. figyelmeztetési hullám

A felület tagjai nem deklarálhatnak statikus osztályt tartalmazó visszatérési típust. Az alábbi kód a CS8897-et és a CS8898-at is bemutatja:

public static class Utilities
{
    // elided
}

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

    // CS8898
    public Utilities GetUtility();
}

A figyelmeztetés kijavításához módosítsa a visszatérési típust, vagy távolítsa el a metódust.