Phakathi no-2025, iqela le-PVS-Studio iye uyifake ngokushesha iiprojekthi ze-open-source C#. Phakathi noyonyaka, sinamathela iziphumo ezininzi. Ngakho, sinikeza iziphumo ezingu-10 ezininzi ezinzima kusuka ku-variety enhle. Sincoma ukuthi uzothola le roundup enhle futhi enhle. Enjoy! Ungayifaka kanjani i-top? Kukho izimo eziningana ukuthi ikhowudi leprojekthi kufanele ibekwe ukuze uthole indawo ku-top list yethu: it kuqala nge-open-source project; izimo zihlanganiswa PVS-Studio; ikhodi ngokuvamile iqukethe i-error; ikhodi kuyinto enhle ukuhlola; Yonke ingcindezi kuyinto eyodwa. Njengoba sinikeza izifundo ezivamile, sinikeza isithombe esithakazelisayo ze-error. Ungathola i-articles kusuka kumahora ezidlulile lapha: Top 10 Izinzuzo Zezıhlabane ngo-2024 Top 10 Izinzuzo Zezıhlabane ngo-2023 Top 10 Izinzuzo Zezıhlabane ngo-2022 Top 10 imiphumela ngo-2021 Top 10 izimpendulo ngo-2020 Top 10 Izinzuzo Zezıhlabane ngo-2019 Ngaphezu kwalokho, sicela siphinde emangalisayo emangalisayo we-C# errors ye-2025! P.S. Umbhali wesixhumanisi wahlanganisa futhi wahlanganisa imibuzo ngokuvumelana nemibuzo yayo. Uma ungenza lokhu noma lokhu ibhokisi ukhonza indawo eyodwa, sicela ushiye amazwana :) 10th indawo. Thola lokhu Umhlahlandlela wesitimela usuku lokuqala nge-error ebizwa ku- I- .NET 9 iboniswe ngokushesha, kodwa i-.NET 10 iboniswe ngenyanga embalwa. . Umbhalo mayelana nokuphathwa .NET 9 Umhlahlandlela Ngiyaxolisa kwama-analysis: public static void SetAsIConvertible(this ref ComVariant variant, IConvertible value) { TypeCode tc = value.GetTypeCode(); CultureInfo ci = CultureInfo.CurrentCulture; switch (tc) { case TypeCode.Empty: break; case TypeCode.Object: variant = ComVariant.CreateRaw(....); break; case TypeCode.DBNull: variant = ComVariant.Null; break; case TypeCode.Boolean: variant = ComVariant.Create<bool>(....)); break; case TypeCode.Char: variant = ComVariant.Create<ushort>(value.ToChar(ci)); break; case TypeCode.SByte: variant = ComVariant.Create<sbyte>(value.ToSByte(ci)); break; case TypeCode.Byte: variant = ComVariant.Create<byte>(value.ToByte(ci)); break; case TypeCode.Int16: variant = ComVariant.Create(value.ToInt16(ci)); break; case TypeCode.UInt16: variant = ComVariant.Create(value.ToUInt16(ci)); break; case TypeCode.Int32: variant = ComVariant.Create(value.ToInt32(ci)); break; case TypeCode.UInt32: variant = ComVariant.Create(value.ToUInt32(ci)); break; case TypeCode.Int64: variant = ComVariant.Create(value.ToInt64(ci)); break; case TypeCode.UInt64: variant = ComVariant.Create(value.ToInt64(ci)); break; case TypeCode.Single: variant = ComVariant.Create(value.ToSingle(ci)); break; case TypeCode.Double: variant = ComVariant.Create(value.ToDouble(ci)); break; case TypeCode.Decimal: variant = ComVariant.Create(value.ToDecimal(ci)); break; case TypeCode.DateTime: variant = ComVariant.Create(value.ToDateTime(ci)); break; case TypeCode.String: variant = ComVariant.Create(....); break; default: throw new NotSupportedException(); } } Enter Full Screen mode Ukufinyelela Full Screen mode Can you see the issue? It's definitely there! case TypeCode.Int64: variant = ComVariant.Create(value.ToInt64(ci)); break; case TypeCode.UInt64: variant = ComVariant.Create(value.ToInt64(ci)); break; // <= Enter Full Screen mode Ukufinyelela Full Screen mode PVS-Studio Ukukhangisa: Izigaba ezimbili noma ezingaphezu ze-case-branches zenza imisebenzi efanayo. DynamicVariantExtensions.cs 68 V3139 Ngingathanda ukuthi uthatha imibuzo emangalisayo emzimbeni yakho, futhi ukubukeka kwakho emangalisayo awukwazi ukujabulela. instead of , ama-developer kufanele usebenzisa i-existing method. This may be a copy-paste error. case TypeCode.UInt64 value.ToInt64 ToUInt64() 9th indawo. Invalid format I-ninth place ivela ku-error ebizwa ku- : inqaku mayelana nokuphathwa ne-Neo ne-NBitcoin amaphrojekthi public override string ToString() { var sb = new StringBuilder(); sb.AppendFormat("{1:X04} {2,-10}{3}{4}", Position, OpCode, DecodeOperand()); return sb.ToString(); } Enter Full Screen mode Ukufinyelela Full Screen mode PVS-Studio warning: [CWE-685] I-format ebuthakathaka. Inani elilinganiselwe yama-format ebuthakathaka lapho uxhumana ne-AppendFormat. Ama-format ebuthakathaka: {3}, {4}. I-arguments ebuthakathaka: 1st. VMInstruction.cs 105 Ukuhlobisa Thola i-Overridden indlela inevitably kusenza isizukulwane. Lokhu kubangelwa Ukubalwa okuqukethe amaphuzu amabili. ToString sb.AppendFormat Inani le-arguments esithathwe kuyinto engaphansi kuka-placeholders ku-format string, okuholela isizukulwane. Ngaphandle kokufinyelelwa kwelanga lokuqala ngokubhalisa inani le-arguments kanye ne-placeholders, isixazululo iyaziqhathanisa isixazululo. Kuyinto ngenxa yokufinyelela kwe-placeholder kuqala ku-0, futhi akuyona 1. Lokhu kubalulekile ukuba isixazululo se-placeholder enesiquguqukayo nge-index 4, okuyinto ayikho. 8th indawo. Navel-gazing Umthombo we-Error kuqala ku-The : Umbhalo mayelana nokuVavanyelwa Lean Trading Engine public override int GetHashCode() { unchecked { var hashCode = Definition.GetHashCode(); var arr = new int[Legs.Count]; for (int i = 0; i < Legs.Count; i++) { arr[i] = Legs[i].GetHashCode(); } Array.Sort(arr); for (int i = 0; i < arr.Length; i++) { hashCode = (hashCode * 397) ^ arr[i]; } return hashCode; } } public override bool Equals(object obj) { .... return Equals((OptionStrategyDefinitionMatch) obj); } Enter fullscreen mode Exit fullscreen mode PVS-Studio Ukukhangisa: Isakhiwo se- 'Legs' isetshenziselwa inqubo ye- 'GetHashCode' kodwa ayikho inqubo ye- 'Equals'. OptionStrategyDefinitionMatch.cs 176 Waze3192 I-Analytics I-Analytics Hlola ku Method, okuyinto ibizwa ngokuthi overridden , and found that it doesn't use the Umkhakha, kodwa Ngena ngemvume Ukucubungula Equals Equals Legs GetHashCode Thina ucwaningo oluthile le Ukucaciswa: Equals public bool Equals(OptionStrategyDefinitionMatch other) { .... var positions = other.Legs .ToDictionary(leg => leg.Position, leg => leg.Multiplier); foreach (var leg in other.Legs) // <= { int multiplier; if (!positions.TryGetValue(leg.Position, out multiplier)) { return false; } if (leg.Multiplier != multiplier) { return false; } } return true; } Enter Full Screen mode Ukufinyelela Full Screen mode Qaphela ukuthi indlela iterates phezu . For each element in that collection, the code tries to find it in the isixazululo - kodwa lokhu isixazululo kwenziwa Ngenxa yalokho, ikhowudi ukulawula ukuba izakhiwo ze-collection zihlanganisa ku-collection efanayo. other.Legs positions other.Legs Thina ukuguqulwa ikhodi ngokuguqulwa Nge ekubeni indawo ekubeni. other.Legs Legs indawo 7 Tricky Equals I-seventh place ivela ku-error kusuka ku- : Umbhalo ku-Checking ScottPlot public class CoordinateRangeMutable : IEquatable<CoordinateRangeMutable> { .... public bool Equals(CoordinateRangeMutable? other) { if (other is null) return false; return Equals(Min, other.Min) && Equals(Min, other.Min); // <= } public override bool Equals(object? obj) { if (obj is null) return false; if (obj is CoordinateRangeMutable other) return Equals(other); return false; } public override int GetHashCode() { return Min.GetHashCode() ^ Max.GetHashCode(); // <= } } Enter Full Screen mode Ukufinyelela Full Screen mode PVS-Studio izibuyekezo Isakhiwo se- 'Max' isetshenziswe ku-'GetHashCode' isakhiwo kodwa ayikho ku-'Equals' isakhiwo. ScottPlot CoordinateRangeMutable.cs 198 Waze3192 I-Equals(Min, other.Min) kuyinto i-sub-expressions efanayo emanzini futhi emzimbeni ye-operator '&&'. ScottPlot CoordinateRangeMutable.cs 172 Ukubuyekezwa I-analyzer ivumela izibuyekezo ezimbili ngenxa ye-fragment ye-code. Bona ukuthi lokhu kwenziwa. Thola kuqala nge I-Analytics warning ivumela ukuthi I-property isetshenziswa ku- Method, kodwa akuyona Method. Uma usihlobene i-overridden indlela, singakwazi ukubona ukuthi enye isivela emzimbeni yayo. At there we can see the following: I-The isisombululo esifundisa lokhu ingxenye. Waze3192 Max GetHashCode Equals Equals Equals Equals(Min, other.Min) && Equals(Min, other.Min) V3001 Ngokuvamile, omunye I-Operand must have the Ukuhlobisa && Equals(Max, other.Max) Ngiyaxazululo - Ukubonisa ku- Ukulinganisa Max Equals Isigaba se-6: Bit Tricks Umlilo owenziwe, njenge elandelayo, kusuka ku- , concludes the first half of the top: article on checking ScottPlot public static Interactivity.Key GetKey(this Keys keys) { Keys keyCode = keys & ~Keys.Modifiers; // <= Interactivity.Key key = keyCode switch { Keys.Alt => Interactivity.StandardKeys.Alt, // <= Keys.Menu => Interactivity.StandardKeys.Alt, Keys.Shift => Interactivity.StandardKeys.Shift, // <= Keys.ShiftKey => Interactivity.StandardKeys.Shift, Keys.LShiftKey => Interactivity.StandardKeys.Shift, Keys.RShiftKey => Interactivity.StandardKeys.Shift, Keys.Control => Interactivity.StandardKeys.Control, // <= Keys.ControlKey => Interactivity.StandardKeys.Control, Keys.Down => Interactivity.StandardKeys.Down, Keys.Up => Interactivity.StandardKeys.Up, Keys.Left => Interactivity.StandardKeys.Left, Keys.Right => Interactivity.StandardKeys.Right, _ => Interactivity.StandardKeys.Unknown, }; .... } Enter fullscreen mode Exit fullscreen mode PVS-Studio Ukukhangisa: Unreachable code detected. The 'case' value is out of range of the match expression. ScottPlot.WinForms FormsPlotExtensions.cs 106 Ukuhlobisa I-Multiple Pattern Values ngaphakathi Zonke izindlela ezivamile zihlanganisa. Sicela uchofoze ukuthi lokhu kusebenza. switch Okokuqala, kufanele ucwaningo izibalo ezihambisana nezinhlelo ezingenalutho ze-enumeration. [Flags] [TypeConverter(typeof(KeysConverter))] [Editor(....)] public enum Keys { /// <summary> /// The bit mask to extract modifiers from a key value. /// </summary> Modifiers = unchecked((int)0xFFFF0000), .... /// <summary> /// The SHIFT modifier key. /// </summary> Shift = 0x00010000, /// <summary> /// The CTRL modifier key. /// </summary> Control = 0x00020000, /// <summary> /// The ALT modifier key. /// </summary> Alt = 0x00040000 } Enter Full Screen mode Ukufinyelela Full Screen mode Okulandelayo, thina ukuguqulwa ku-binary: It's clear now that include each of the erroneous enumeration elements. Modifiers I-value yatholakala ku- Kutholwe kusuka ku expression. This expression excludes the Imininingwane . In addition to , however, Ngena ngemva , futhi Ngaphezu kwalokho, kungenzeka ukuthi zihlanganisa lezi zibonelelo ( has a non-zero bit for each non-zero bit of the erroneous enumeration elements). switch keys & ~Keys.Modifiers Keys.Modifiers keys Keys.Modifiers Shift Control Alt Modifiers Modifiers Ngokusho konke, singatholakala ukuthi ukuguqulwa kwe-bit eyenza Ngena ngemva , noma Ukuze Ukusebenza kungekho. Shift Control Alt keys & ~Keys.Modifiers Umthombo kungaba ku- Ukukhiqizwa kunoma ama-enumeration values. switch indawo 5th. All boxed up I-Top Five kuqala ne-error ebizwa ku-a : Umbhalo mayelana nokuphathwa .NET 9 struct StackValue { .... public override bool Equals(object obj) { if (Object.ReferenceEquals(this, obj)) return true; if (!(obj is StackValue)) return false; var value = (StackValue)obj; return this.Kind == value.Kind && this.Flags == value.Flags && this.Type == value.Type; } } Enter Full Screen mode Ukufinyelela Full Screen mode PVS-Studio warning: Comparing value type variables with 'ReferenceEquals' is incorrect because 'this' will be boxed. ILImporter.StackValue.cs 164 V3161 Waze Ukulungiselela i-parameter ye- usayizi. Uma usayizi lithunyelwe, lithunyelwe . The reference created on the heap won't match any other reference. ReferenceEquals Object Ukuhlobisa ukususela isithunyelwe njengesiqingatha yokuqala, i-boxing iyatholakala ngalinye method is called. So, checking via ikhaya . this Equals ReferenceEquals false Qaphela ukuthi le ngempumelelo akuyona indlela yokusebenza. Nokho, ukubuyekeza usebenzisa indlela yasungulwa ukuze ukunceda ukuxhumana okuqhubekayo uma izibuyekezo zihlanganisa. Ngokuvamile, lokhu kuyinto uhlobo lokuphumula. Ngokuvamile, kunjalo, indawo kuyinto ephakeme ngokuphelele: ReferenceEquals ikhowudi kusebenza njalo emva kokucwaninga; each call to results in a boxing operation. Equals I-analyzer eyakhelwe ku- .NET (ukulawula ) iguquguquka le nkqubo. Nokho, ama-developer ye-.NET ngokuvamile awukwazi ukuvikela :) CA2013 Mhlawumbe okuhlobene le nkqubo. Ngaphezu kwalokho, ifakwe ngokuvamile ukusuka ku .NET 5. UKUSEBENZA 2013 4th place. Unsubscribing Isigaba se-4. Isikhathi esifundeni esifundeni : Umbhalo mayelana nokulawula i-MSBuild private static void SubscribeImmutablePathsInitialized() { NotifyOnScopingReadiness?.Invoke(); FileClassifier.Shared.OnImmutablePathsInitialized -= () => NotifyOnScopingReadiness?.Invoke(); } Enter Full Screen mode Ukufinyelela Full Screen mode PVS-Studio warning: . Anonymous function is used to unsubscribe from 'OnImmutablePathsInitialized' event. No handlers will be unsubscribed, as a separate delegate instance is created for each anonymous function declaration. CheckScopeClassifier.cs 67 V3084 Ngokuvamile, ukuguqulwa kwe-delegate akufanele akufanele, ngoba ngalinye i-function ye-anonymous ifakwe, isithombe esitsha se-delegate ifakwe. Ngenxa yalokho, ukulanda ukuguqulwa kwe-delegate esithile akufanele isiphumo esifanele. Ngena ngemvume kodwa unsubscribe kusukela , which has no effect. OnImmutablePathsInitialized delegate 1 delegate 2 3rd place. Confusion over operator precedence Okunye, siphinde i-top three. I-error kusuka ku- Thola indawo yesithathu enhle: inqaku mayelana nokuphathwa ne-Neo ne-NBitcoin amaphrojekthi public override int Size => base.Size + ChangeViewMessages?.Values.GetVarSize() ?? 0 + 1 + PrepareRequestMessage?.Size ?? 0 + PreparationHash?.Size ?? 0 + PreparationMessages?.Values.GetVarSize() ?? 0 + CommitMessages?.Values.GetVarSize() ?? 0; Enter Full Screen mode Ukufinyelela Full Screen mode PVS-Studio Ukukhangisa: [CWE-783] Mhlawumbe i-operator '??' isebenza ngezindlela ezahlukile kunesithathwa. I-priority yayo iyatholakala ngaphansi kwe-priority ye-other operators e-left. RecoveryMessage.cs 35 V3123 The analyzer issued several izibuyekezo ngoba lokhu ikhodi, kodwa i-imeyile nje ngenxa yokubhalisa. I umphathi we-operator inesibini engaphansi kunazo Kodwa-ke, ukucubungula le-expression kubonisa abathuthukisi abalandeli okungenani. Ukungena ngemvume ?? + Ingabe ikheli le-operations kubaluleke lapha? Ukuze uthole impendulo, bheka isibonelo ye-sub-expression add-on if is : ChangeViewMessages null base.Size + ChangeViewMessages?.Values.GetVarSize() ?? 0 Enter fullscreen mode Exit fullscreen mode Ngaphandle kwe- isilinganiso, umphumela we-sub-expression kuyinto 0 ngoba ukwandisa to results in . base.Size base.Size null null Uma siphinde e-parentheses, ukuguqulwa kwe-operation order, imiphumela ivela . ChangeViewMessages?.Values.GetVarSize() ?? 0 base.Size Ikheli le-2: I-The Traacherous Pattern indawo yesibili uya ku-error kusuka ku- : article about checking the Files file manager protected void ChangeMode(OmnibarMode? oldMode, OmnibarMode newMode) { .... var modeSeparatorWidth = itemCount is not 0 or 1 ? _modesHostGrid.Children[1] is FrameworkElement frameworkElement ? frameworkElement.ActualWidth : 0 : 0; .... } Enter fullscreen mode Exit fullscreen mode PVS-Studio Ukukhangisa: [CWE-670] The 'not 0 or 1' logical pattern may not work as expected. The 'not' pattern is matched only to the first expression from the 'or' pattern. Files.App.Controls Omnibar.cs 149 Waze3207 Sishayele ngokushesha ku-The ingxenye. Uyazi ukuthi yini ingxaki? Le pattern iyahlukile. I-part II yayo akuyona akukho. itemCount is not 0 or 1 Uma wathi "x akuyona 0 noma 1", abantu ngokuvamile zihlanganisa ukuthi x akuyona noma 0 noma 1. Nokho, ku-C#, i-operator precedence isebenza ngokufanayo— actually means Izinzuzo ezivela kuphela ku-redundancy kodwa futhi ku-errors like Ukusabela okuhlobene ku-A Ngokusekelwe kwebhizinisi, noma i-compiler iyathola le ngempumelelo elandelayo, noma uchungechunge lwesakhiwo se-static izibambisane njenge-akhawunti. x is not 0 or 1 x is (not 0) or 1 NullReferenceException: list is not null or list.Count == 0 Ukubuyiselwa 1st place. How does LINQ work? And the winner is an error from an . This error ranks first due to its subtlety. Some developers may not consider the effects of using deferred execution methods in combination with captured variables. All the details are below: Umbhalo mayelana nokuvamile Lean Trading Engine public void FutureMarginModel_MarginEntriesValid(string market) { .... var lineNumber = 0; var errorMessageTemplate = $"Error encountered in file " + $"{marginFile.Name} on line "; var csv = File.ReadLines(marginFile.FullName) .Where(x => !x.StartsWithInvariant("#") && !string.IsNullOrWhiteSpace(x)) .Skip(1) .Select(x => { lineNumber++; // <= .... }); lineNumber = 0; // <= foreach (var line in csv) { lineNumber++; // <= .... } } Enter fullscreen mode Exit fullscreen mode PVS-Studio Ukukhangisa: The 'lineNumber' variable was changed after it was captured in a LINQ method with deferred execution. The original value will not be used when the method is executed. FutureMarginBuyingPowerModelTests.cs 720 Ukuhlobisa Waze I-variable ifakwe futhi ifakwe ku-delegate eyenziwa ku-LINQ method. Njengoba is a delayed method, idivayisi ye-delegate isebenza ngenkathi i-iterating phezu kwekhompyutha esithathwe, akuyona lapho Ukubhatalwa lineNumber Select Select Nge-Iterating Over The Ukwakhiwa, The variable futhi iyahlekile. Ngenxa yalokho, ngalinye iteration iyahlekile : when the delegate runs and inside the , which looks odd. csv lineNumber lineNumber by 2 foreach Waze Ukubuyekezwa ngaphambi . It's likely that developers expected that this variable could hold a non-zero value before the loop. However, that is impossible: kuqala ku-zero, futhi indawo eyodwa esebenzayo ngaphambi kwe- sits in the delegate. As mentioned above, the delegate runs during iteration, not before it. Apparently, the developers expected the delegate to execute prior to entering the loop. lineNumber = 0 foreach lineNumber foreach Ukuphakama That's it! We've gone through the most interesting warnings from the author's point of view :) Ngingathanda ukuthi ungathanda le khulula esithakazelisayo futhi esithakazelisayo ngokuhambisana nokuthuthukiswa kwe-code. If you'd like to check whether your project has similar issues, now's the time to use a static analyzer. Here's the . Ukulandelela Link