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.