Die 10 häufigsten Fehler in C # -Projekten im Jahr 2019

Bild 1

Hallo an alle Fans von Bugs! Das neue Jahr steht vor der Tür, also ist es Zeit, Bilanz über das neue Jahr zu ziehen. Wir freuen uns, Ihnen die Liste der häufigsten vom PVS-Studio-Team gefundenen Fehler in offenen C # -Projekten im Jahr 2019 vorlegen zu können. Fertig? Dann lass uns loslegen.

Zehnter Platz "Fool everyone"


V3066 Mögliche falsche Reihenfolge der an die 'AdjustCellBorderStyle'-Methode übergebenen Argumente:' isFirstDisplayedRow 'und' isFirstDisplayedColumn '. DataGridViewComboBoxCell.cs 1934

protected override void OnMouseMove(DataGridViewCellMouseEventArgs e) { .... dgvabsEffective = AdjustCellBorderStyle( DataGridView.AdvancedCellBorderStyle, dgvabsPlaceholder, singleVerticalBorderAdded, singleHorizontalBorderAdded, isFirstDisplayedRow, // <= isFirstDisplayedColumn); // <= .... } 

Der Fehler aus dem Artikel " WinForms: Errors, Holmes ". Der Analysator weist darauf hin, dass wenn zwei letzte Argumente der Methode verwechselt werden. Schauen wir uns die AdjustCellBorderStyle- Deklaration an:

 public virtual DataGridViewAdvancedBorderStyle AdjustCellBorderStyle( DataGridViewAdvancedBorderStyledataGridViewAdvancedBorderStyleInput, DataGridViewAdvancedBorderStyle dataGridViewAdvancedBorderStylePlaceholder, bool singleVerticalBorderAdded, bool singleHorizontalBorderAdded, bool isFirstDisplayedColumn, bool isFirstDisplayedRow) { .... } 

Sieht aus wie der Analysator richtig ist. Oft übergeben Entwickler einige Argumente absichtlich in umgekehrter Reihenfolge, um beispielsweise Variablen auszutauschen. Aber es sieht nicht so aus. Zunächst werden die Variablen vom Typ bool vertauscht . Zweitens gibt es keine ungewöhnlichen Methodennamen: kein "Swap" oder "Reverse". Darüber hinaus ist es nicht so schwierig, einen solchen Fehler zu machen: Die Sortierreihenfolge "Zeile / Spalte" wird von den Menschen unterschiedlich wahrgenommen.

Neunter Platz "Der Ewigkeit so nah"


V3110 Mögliche unendliche Rekursion innerhalb der Methode 'TryValidateModel'. PrefixedModuleUpdater.cs 48

 public bool TryValidateModel(object model, string prefix) { return TryValidateModel(model, Prefix(prefix)); } 

Der Fehler aus dem Artikel " Scannen des Codes von Orchard CMS auf Bugs ". Es gab einen Fehler, der zu einer unendlichen Rekursion führte. Um zu verstehen, wie der Fehler gemacht wurde, muss die Überladung der TryValidateModel- Methode berücksichtigt werden:

 public bool TryValidateModel(object model) { return _updateModel.TryValidateModel(model); } 

Es ist wahrscheinlich, dass der erste Fall auch einen solchen Aufruf verwenden sollte:

 public bool TryValidateModel(object model, string prefix) { return _updateModel.TryValidateModel(model, Prefix(prefix)); } 

Der Code wurde erfolgreich kompiliert, da _updateModel vom Typ IUpdateModel ist und die aktuelle Klasse auch die Schnittstelle IUpdateModel implementiert.

Achte Stelle "Finde mich, wenn du kannst"


V3091 Empirische Analyse. Es ist möglich, dass das Zeichenfolgenliteral einen Tippfehler enthält: "Verwaltungsgruppen-ID". Das Wort 'Id' ist verdächtig. Konstanten.cs 36

 public class HelpMessages { public const string SubscriptionId = "Subscription Id of the subscription associated with the management"; public const string GroupId = "Management Group Id"; // <= public const string Recurse = "Recursively list the children of the management group"; public const string ParentId = "Parent Id of the management group"; public const string GroupName = "Management Group Id"; // <= public const string DisplayName = "Display Name of the management group"; public const string Expand = "Expand the output to list the children of the management group"; public const string Force = "Force the action and skip confirmations"; public const string InputObject = "Input Object from the Get call"; public const string ParentObject = "Parent Object"; } 

Der Fehler aus dem Artikel " Azure PowerShell: Mostly Harmless ". Der Analysator vermutete, dass die GroupName- Konstante durch eine falsche Zeichenfolge initialisiert wurde. Es sollte wahrscheinlich so etwas wie "Name der Verwaltungsgruppe" geben . Die Kritikalität dieses Fehlers ist immer noch fraglich, aber der Fehler ist definitiv selten und schwer zu erkennen.

Siebter Platz "Just underlooked"


V3078 Die ursprüngliche Sortierreihenfolge geht nach wiederholtem Aufruf der 'OrderBy'-Methode verloren. Verwenden Sie die 'ThenBy'-Methode, um die ursprüngliche Sortierung beizubehalten. GridModel.Selection.cs 107

 internal partial class GridModel { private void BuildCellSelectionRegions(....) { .... this.MergeCellSelectionRegions(selectedItemsInView .OrderBy(c => c.Column.ItemInfo.LayoutInfo.Line) .OrderBy(c => c.RowItemInfo.LayoutInfo.Line)); } } 

Der Fehler aus dem Artikel " Überprüfen der Telerik-Benutzeroberfläche auf UWP als Einstieg in PVS-Studio ". Das Ergebnis der vorherigen Sortierung geht aufgrund eines wiederholten Aufrufs von OrderBy für die bereits sortierte Sammlung verloren. In diesem Fall muss ThenBy verwendet werden:

 this.MergeCellSelectionRegions(selectedItemsInView .OrderBy(c => c.Column.ItemInfo.LayoutInfo.Line) .ThenBy(c => c.RowItemInfo.LayoutInfo.Line)); 

Solche Fehler entstehen durch Unachtsamkeit oder Unwissenheit. Ich denke, Copy-Paste ist hier schuld.

Sechster Platz "Der Code ist dokumentiert", sagten sie


V3009 Es ist merkwürdig, dass diese Methode immer den gleichen Wert von 'true' zurückgibt. MaskedTextProvider.cs 1529

 public bool Remove(out int testPosition, out MaskedTextResultHint resultHint) { .... if (lastAssignedPos == INVALID_INDEX) { .... return true; // nothing to remove. } .... return true; } 

Der Fehler aus dem Artikel " Überprüfen des .NET Core Libraries-Quellcodes mit dem PVS-Studio Static Analyzer ". Die Methode gibt immer true zurück . Ja, es ist ein Fehler, aber es gibt noch eine andere Sache, die wirklich neugierig ist. Der Methode folgt der ausführliche Kommentar:

Entfernt das letzte Zeichen aus der formatierten Zeichenfolge. (Letztes Zeichen in virtueller Zeichenfolge entfernen). Beim Beenden enthält der Parameter out die Position, an der die Operation tatsächlich ausgeführt wurde. Diese Position ist relativ zum Teststring. Der Parameter MaskedTextResultHint out gibt weitere Informationen zum Operationsergebnis. Gibt bei Erfolg true zurück , andernfalls false .

Achte auf den letzten Satz. Wer liest diese Kommentare überhaupt? Wenn wir es jedoch ernst nehmen, wird ein solcher Fehler leicht unterstellt, beispielsweise beim Refactoring oder Debuggen. Nun, die Autoren wollten die Variante überprüfen, wenn das Ergebnis der Methode immer wahr ist , vergaßen jedoch, alles so zurückzugeben, wie es war.

Fünfter Platz "Index mich jetzt!"


V3102 Verdächtiger Zugriff auf ein Element eines ' seq' -Objekts durch einen konstanten Index innerhalb einer Schleife. XmlQueryRuntime.cs 738

 public bool MatchesXmlType(IList<XPathItem> seq, ....) { .... for (int i = 0; i < seq.Count; i++) { if (!CreateXmlType(seq[0]).IsSubtypeOf(....)) return false; } return true; } 

Der Fehler aus dem Artikel " Überprüfen des .NET Core Libraries-Quellcodes mit dem PVS-Studio Static Analyzer ". Beim Durchlaufen der seq- Auflistung in der for- Schleife verwendet der Entwickler fälschlicherweise den Zugriff nur auf das erste Element aller Iterationen (Index 0 anstelle von i ).

Vierter Platz "Nur ein Dollar knapp"


V3138 String-Literal enthält einen möglichen interpolierten Ausdruck. Betrachten Sie die Inspektion: e. SSPIHandleCache.cs 42

 internal static void CacheCredential(SafeFreeCredentials newHandle) { try { .... } catch (Exception e) { if (!ExceptionCheck.IsFatal(e)) { NetEventSource.Fail(null, "Attempted to throw: {e}"); } } } 

Der Fehler aus dem Artikel " Überprüfen des .NET Core Libraries-Quellcodes mit dem PVS-Studio Static Analyzer ". Anscheinend sollte der String "Versuch zu werfen: {e}" interpoliert werden. Aufgrund des fehlenden $ -Zeichens wird die Zeilendarstellung der e- Ausnahme nicht in die Zeichenfolge eingefügt. Infolgedessen wird die Zeile "so wie sie ist" verwendet.

Dritter Platz „Es gibt keinen Ausweg“


V3008 [CWE-563] Der Variablen 'this.linker.s3.region' werden nacheinander zweimal Werte zugewiesen. Vielleicht ist das ein Fehler. Zeilen prüfen: 116, 114. AWSSDK.DynamoDBv2.Net45 S3Link.cs 116

 public string Region { get { .... } set { if (String.IsNullOrEmpty(value)) { this.linker.s3.region = "us-east-1"; } this.linker.s3.region = value; } } 

Der Fehler aus dem Artikel " Suchen nach Fehlern im Amazon Web Services SDK-Quellcode für .NET ". Return wurde im Body des if- Blocks verpasst. Infolgedessen erhält die Variable this.linker.s3.region immer einen Wert, einschließlich einer leeren Zeile und null.

Zweiter Platz "Richtiges Kleid!"


V3070 Nicht initialisierte Variable 'LANG_USER_DEFAULT' wird beim Initialisieren der Variablen 'LOCALE_USER_DEFAULT' verwendet. NativeMethods.cs 890

 internal static class NativeMethods { .... public static readonly int LOCALE_USER_DEFAULT = MAKELCID(LANG_USER_DEFAULT); public static readonly int LANG_USER_DEFAULT = MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT); .... } 

Der Fehler aus dem Artikel " WinForms: Errors, Holmes ". Die Initialisierungsreihenfolge von Klassenfeldern ist verwirrt. Um den Wert des Feldes LOCALE_USER_DEFAULT zu berechnen, wird das Feld LANG_USER_DEFAULT verwendet, das derzeit noch nicht initialisiert ist und den Wert 0 hat. Die Variable wird an keiner Stelle im Code weiter verwendet. Um herauszufinden, wozu dieser Fehler führt, wurde ein komplettes Testprogramm geschrieben, das Methoden aus WinForms-Code enthält. Anstelle einiger verwendeter Konstanten wurden der Einfachheit halber ihre tatsächlichen Werte eingesetzt:

 internal static class NativeMethods { public static readonly int LOCALE_USER_DEFAULT = MAKELCID(LANG_USER_DEFAULT); public static readonly int LANG_USER_DEFAULT = MAKELANGID(0x00, 0x01); public static int MAKELANGID(int primary, int sub) { return ((((ushort)(sub)) << 10) | (ushort)(primary)); } public static int MAKELCID(int lgid) { return MAKELCID(lgid, 0x0); } public static int MAKELCID(int lgid, int sort) { return ((0xFFFF & lgid) | (((0x000f) & sort) << 16)); } } class Program { static void Main() { System.Console.WriteLine(NativeMethods.LOCALE_USER_DEFAULT); } } 

Als Ergebnis der Ausführung erhalten wir Folgendes: 0. Beheben wir nun den Fehler, indem wir die Deklaration der Felder LOCALE_USER_DEFAULT und LANG_USER_DEFAULT vertauschen . Ergebnis der Programmausführung: 1024.

Erster Platz "Erst versuchen, dann vertrauen"


Mit dem ersten Platz ist es nie einfach. Hier muss etwas Außergewöhnliches und Faszinierendes sein. Anfangs habe ich für diesen Artikel mehr als zwanzig interessante Fehler ausgewählt, aber es gab nichts, was den ersten Platz unter ihnen verdient hätte. Damals erinnerte ich mich an den Artikel meines Kollegen Sergey Vasiliev. Der Artikel ging nur auf einen einzelnen Fehler ein. Das Schöne an diesem Fehler ist, dass er die Arbeit unseres Analysators direkt beeinflusst. Wie? Sie können es bereits aus dem Titel des Artikels abrufen: " Die Geschichte, wie PVS-Studio einen Fehler in der in ... PVS-Studio verwendeten Bibliothek gefunden hat ". Hier fühlte ich mich zu faul, um den Fehler zu beschreiben, und würde daher vorschlagen, dass Sie dem Link folgen und die Details herausfinden. :) Ich garantiere, es lohnt sich. Darüber hinaus ist der Artikel kurz.

Fazit


Ich hoffe, die Fehler waren für Sie ausstehend und der Artikel war nicht anstrengend. Sie können jederzeit den PVS-Studio-Analysator herunterladen , um Fehler in Ihren Projekten und in Projekten von Drittanbietern zu finden, die Sie, Ihre Kollegen und jeden Tom, Dick oder Harry zufriedenstellen. Lass die Fehler kleiner sein und Zeit für Selbstverbesserung - mehr! :)

Hast du bis zum Ende gelesen? Herzlichen Glückwunsch zum Erreichen des neuen Levels! Verpassen Sie nicht unsere neuesten Artikel in unserem Blog - die besten Fehler in Java- und C ++ - Projekten, die 2019 gefunden wurden.

Bild 2

Source: https://habr.com/ru/post/de481174/


All Articles