diff --git a/Common.ruleset b/Common.ruleset index 640e31b866..147a92f576 100644 --- a/Common.ruleset +++ b/Common.ruleset @@ -22,6 +22,12 @@ + + + + + + diff --git a/ExternalProjects/BizHawk.Analyzer/UseNameofOperatorAnalyzer.cs b/ExternalProjects/BizHawk.Analyzer/UseNameofOperatorAnalyzer.cs new file mode 100644 index 0000000000..31140b2d67 --- /dev/null +++ b/ExternalProjects/BizHawk.Analyzer/UseNameofOperatorAnalyzer.cs @@ -0,0 +1,69 @@ +namespace BizHawk.Analyzers; + +using System.Collections.Immutable; + +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Diagnostics; + +[DiagnosticAnalyzer(LanguageNames.CSharp)] +public sealed class UseNameofOperatorAnalyzer : DiagnosticAnalyzer +{ + private static readonly DiagnosticDescriptor DiagNoToStringOnType = new( + id: "BHI1103", + title: "Don't call typeof(T).ToString(), use nameof operator or typeof(T).FullName", + messageFormat: "Replace typeof({0}){1} with either nameof({0}) or typeof({0}).FullName", + category: "Usage", + defaultSeverity: DiagnosticSeverity.Warning, + isEnabledByDefault: true); + + private static readonly DiagnosticDescriptor DiagUseNameof = new( + id: "BHI1102", + title: "Don't call typeof(T).Name, use nameof operator", + messageFormat: "Replace typeof({0}).Name with nameof({0})", + category: "Usage", + defaultSeverity: DiagnosticSeverity.Error, + isEnabledByDefault: true); + + public override ImmutableArray SupportedDiagnostics { get; } = ImmutableArray.Create(DiagNoToStringOnType, DiagUseNameof); + + public override void Initialize(AnalysisContext context) + { + context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); + context.EnableConcurrentExecution(); + ISymbol? memberInfoDotNameSym = null; + ISymbol? typeDotToStringSym = null; + context.RegisterSyntaxNodeAction( + snac => + { + memberInfoDotNameSym ??= snac.Compilation.GetTypeByMetadataName("System.Reflection.MemberInfo")!.GetMembers("Name")[0]; + typeDotToStringSym ??= snac.Compilation.GetTypeByMetadataName("System.Type")!.GetMembers("ToString")[0]; + var toes = (TypeOfExpressionSyntax) snac.Node; + switch (toes.Parent) + { + case BinaryExpressionSyntax bes: + if ((ReferenceEquals(toes, bes.Left) ? bes.Right : bes.Left) is LiteralExpressionSyntax { Token.RawKind: (int) SyntaxKind.StringLiteralToken }) + { + snac.ReportDiagnostic(Diagnostic.Create(DiagNoToStringOnType, toes.GetLocation(), toes.Type.GetText(), " in string concatenation")); + } + break; + case InterpolationSyntax: + snac.ReportDiagnostic(Diagnostic.Create(DiagNoToStringOnType, toes.GetLocation(), toes.Type.GetText(), " in string interpolation")); + break; + case MemberAccessExpressionSyntax maes1: + var accessed = snac.SemanticModel.GetSymbolInfo(maes1.Name).Symbol; + if (memberInfoDotNameSym.Matches(accessed)) + { + snac.ReportDiagnostic(Diagnostic.Create(DiagUseNameof, maes1.GetLocation(), toes.Type.GetText())); + } + else if (typeDotToStringSym.Matches(accessed)) + { + snac.ReportDiagnostic(Diagnostic.Create(DiagNoToStringOnType, maes1.GetLocation(), toes.Type.GetText(), ".ToString()")); + } + break; + } + }, + SyntaxKind.TypeOfExpression); + } +} diff --git a/References/BizHawk.Analyzer.dll b/References/BizHawk.Analyzer.dll index cfa7f15ff0..54b9ce45fa 100644 Binary files a/References/BizHawk.Analyzer.dll and b/References/BizHawk.Analyzer.dll differ diff --git a/src/BizHawk.Client.EmuHawk/tools/ToolManager.cs b/src/BizHawk.Client.EmuHawk/tools/ToolManager.cs index e91a1fa26b..1d2136e49a 100644 --- a/src/BizHawk.Client.EmuHawk/tools/ToolManager.cs +++ b/src/BizHawk.Client.EmuHawk/tools/ToolManager.cs @@ -131,7 +131,7 @@ namespace BizHawk.Client.EmuHawk if (newTool is Form form) form.Owner = _owner; ServiceInjector.UpdateServices(_emulator.ServiceProvider, newTool); SetBaseProperties(newTool); - var toolTypeName = typeof(T).ToString(); + var toolTypeName = typeof(T).FullName!; // auto settings if (newTool is IToolFormAutoConfig autoConfigTool) { diff --git a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Datacorder/DatacorderDevice.cs b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Datacorder/DatacorderDevice.cs index 5343e0740b..5adefec4ce 100644 --- a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Datacorder/DatacorderDevice.cs +++ b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Datacorder/DatacorderDevice.cs @@ -347,9 +347,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC catch (Exception ex) { // exception during operation - var e = ex; - throw new Exception(typeof(DatacorderDevice).ToString() + - "\n\nTape image file has a valid CDT header, but threw an exception whilst data was being parsed.\n\n" + e.ToString()); + throw new Exception($"{nameof(DatacorderDevice)}\n\nTape image file has a valid CDT header, but threw an exception whilst data was being parsed.\n\n{ex}", ex); } } } diff --git a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Disk/NECUPD765.FDD.cs b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Disk/NECUPD765.FDD.cs index 5375997144..52744f750c 100644 --- a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Disk/NECUPD765.FDD.cs +++ b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Disk/NECUPD765.FDD.cs @@ -775,8 +775,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC if (!found) { - throw new Exception(typeof(DriveState).ToString() + - "\n\nDisk image file could not be parsed. Potentially an unknown format."); + throw new Exception($"{nameof(DriveState)}\n\nDisk image file could not be parsed. Potentially an unknown format."); } } diff --git a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Media/MediaConverter.cs b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Media/MediaConverter.cs index 48f8ce7e2b..954f76c2de 100644 --- a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Media/MediaConverter.cs +++ b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Media/MediaConverter.cs @@ -24,34 +24,25 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC /// public virtual bool IsWriter => false; - protected abstract Type SelfType { get; } + protected abstract string SelfTypeName { get; } /// /// Serialization method /// public virtual void Read(byte[] data) - { - throw new NotImplementedException(SelfType + - "Read operation is not implemented for this converter"); - } + => throw new NotImplementedException($"Read operation is not implemented for {SelfTypeName}"); /// /// DeSerialization method /// public virtual void Write(byte[] data) - { - throw new NotImplementedException(SelfType + - "Write operation is not implemented for this converter"); - } + => throw new NotImplementedException($"Write operation is not implemented for {SelfTypeName}"); /// /// Serializer does a quick check, returns TRUE if file is detected as this type /// public virtual bool CheckType(byte[] data) - { - throw new NotImplementedException(SelfType.ToString() + - "Check type operation is not implemented for this converter"); - } + => throw new NotImplementedException($"Check type operation is not implemented for {SelfTypeName}"); /// /// Converts an int32 value into a byte array diff --git a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Media/Tape/CDT/CdtConverter.cs b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Media/Tape/CDT/CdtConverter.cs index 2e803041b1..dd03153e30 100644 --- a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Media/Tape/CDT/CdtConverter.cs +++ b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Media/Tape/CDT/CdtConverter.cs @@ -26,8 +26,8 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC /// public override bool IsWriter => false; - protected override Type SelfType - => typeof(CdtConverter); + protected override string SelfTypeName + => nameof(CdtConverter); /// /// Working list of generated tape data blocks @@ -167,8 +167,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC if (ident != "ZXTape!" || eotm != 0x1A) { // this is not a valid TZX format file - throw new Exception(typeof(CdtConverter) + - "This is not a valid TZX format file"); + throw new Exception($"{nameof(CdtConverter)}: This is not a valid TZX format file"); } // iterate through each block diff --git a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Datacorder/DatacorderDevice.cs b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Datacorder/DatacorderDevice.cs index 37e225e404..e50989e972 100644 --- a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Datacorder/DatacorderDevice.cs +++ b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Datacorder/DatacorderDevice.cs @@ -311,9 +311,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum catch (Exception ex) { // exception during operation - var e = ex; - throw new Exception(typeof(DatacorderDevice).ToString() + - "\n\nTape image file has a valid TZX header, but threw an exception whilst data was being parsed.\n\n" + e.ToString()); + throw new Exception($"{nameof(DatacorderDevice)}\n\nTape image file has a valid TZX header, but threw an exception whilst data was being parsed.\n\n{ex}", ex); } } @@ -331,9 +329,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum catch (Exception ex) { // exception during operation - var e = ex; - throw new Exception(typeof(DatacorderDevice).ToString() + - "\n\nTape image file has a valid PZX header, but threw an exception whilst data was being parsed.\n\n" + e.ToString()); + throw new Exception($"{nameof(DatacorderDevice)}\n\nTape image file has a valid PZX header, but threw an exception whilst data was being parsed.\n\n{ex}", ex); } } @@ -351,9 +347,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum catch (Exception ex) { // exception during operation - var e = ex; - throw new Exception(typeof(DatacorderDevice).ToString() + - "\n\nTape image file has a valid CSW header, but threw an exception whilst data was being parsed.\n\n" + e.ToString()); + throw new Exception($"{nameof(DatacorderDevice)}\n\nTape image file has a valid CSW header, but threw an exception whilst data was being parsed.\n\n{ex}", ex); } } @@ -371,9 +365,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum catch (Exception ex) { // exception during operation - var e = ex; - throw new Exception(typeof(DatacorderDevice).ToString() + - "\n\nTape image file has a valid WAV header, but threw an exception whilst data was being parsed.\n\n" + e.ToString()); + throw new Exception($"{nameof(DatacorderDevice)}\n\nTape image file has a valid WAV header, but threw an exception whilst data was being parsed.\n\n{ex}", ex); } } @@ -390,9 +382,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum catch (Exception ex) { // exception during operation - var e = ex; - throw new Exception(typeof(DatacorderDevice).ToString() + - "\n\nAn exception was thrown whilst data from this tape image was being parsed as TAP.\n\n" + e.ToString()); + throw new Exception($"{nameof(DatacorderDevice)}\n\nAn exception was thrown whilst data from this tape image was being parsed as TAP.\n\n{ex}", ex); } } } diff --git a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Disk/NECUPD765.FDD.cs b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Disk/NECUPD765.FDD.cs index c4aee7d40a..8911b943d0 100644 --- a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Disk/NECUPD765.FDD.cs +++ b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Disk/NECUPD765.FDD.cs @@ -776,8 +776,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum if (!found) { - throw new Exception(typeof(DriveState).ToString() + - "\n\nDisk image file could not be parsed. Potentially an unknown format."); + throw new Exception($"{nameof(DriveState)}\n\nDisk image file could not be parsed. Potentially an unknown format."); } } diff --git a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/MediaConverter.cs b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/MediaConverter.cs index 5425fd46f1..1606160428 100644 --- a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/MediaConverter.cs +++ b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/MediaConverter.cs @@ -26,34 +26,25 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum /// public virtual bool IsWriter => false; - protected abstract Type SelfType { get; } + protected abstract string SelfTypeName { get; } /// /// Serialization method /// public virtual void Read(byte[] data) - { - throw new NotImplementedException(SelfType.ToString() + - "Read operation is not implemented for this converter"); - } + => throw new NotImplementedException($"Read operation is not implemented for {SelfTypeName}"); /// /// DeSerialization method /// public virtual void Write(byte[] data) - { - throw new NotImplementedException(SelfType.ToString() + - "Write operation is not implemented for this converter"); - } + => throw new NotImplementedException($"Write operation is not implemented for {SelfTypeName}"); /// /// Serializer does a quick check, returns TRUE if file is detected as this type /// public virtual bool CheckType(byte[] data) - { - throw new NotImplementedException(SelfType.ToString() + - "Check type operation is not implemented for this converter"); - } + => throw new NotImplementedException($"Check type operation is not implemented for {SelfTypeName}"); /// /// Converts an int32 value into a byte array diff --git a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Tape/CSW/CswConverter.cs b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Tape/CSW/CswConverter.cs index 97429ef4e1..a9dff3ce7e 100644 --- a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Tape/CSW/CswConverter.cs +++ b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Tape/CSW/CswConverter.cs @@ -32,8 +32,8 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum /// public override bool IsWriter => false; - protected override Type SelfType - => typeof(CswConverter); + protected override string SelfTypeName + => nameof(CswConverter); private readonly DatacorderDevice _datacorder; @@ -83,15 +83,13 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum if (ident.ToUpper() != "COMPRESSED SQUARE WAVE") { // this is not a valid CSW format file - throw new Exception(typeof(CswConverter).ToString() + - "This is not a valid CSW format file"); + throw new Exception($"{nameof(CswConverter)}: This is not a valid CSW format file"); } if (data[0x16] != 0x1a) { // invalid terminator code - throw new Exception(typeof(CswConverter).ToString() + - "This image reports as a CSW but has an invalid terminator code"); + throw new Exception($"{nameof(CswConverter)}: This image reports as a CSW but has an invalid terminator code"); } _position = 0; @@ -185,13 +183,11 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum if (compressionType == 1) Array.Copy(data, _position, cswDataUncompressed, 0, cswDataUncompressed.Length); else - throw new Exception(typeof(CswConverter).ToString() + - "CSW Format unknown compression type"); + throw new Exception($"{nameof(CswConverter)}: CSW Format unknown compression type"); } else { - throw new Exception(typeof(CswConverter).ToString() + - "CSW Format Version " + majorVer + "." + minorVer + " is not currently supported"); + throw new Exception($"{nameof(CswConverter)}: CSW Format Version {majorVer}.{minorVer} is not currently supported"); } // create the single tape block diff --git a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Tape/PZX/PzxConverter.cs b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Tape/PZX/PzxConverter.cs index 4d92fd8e50..37c3333207 100644 --- a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Tape/PZX/PzxConverter.cs +++ b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Tape/PZX/PzxConverter.cs @@ -27,8 +27,8 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum /// public override bool IsWriter => false; - protected override Type SelfType - => typeof(PzxConverter); + protected override string SelfTypeName + => nameof(PzxConverter); /// /// Working list of generated tape data blocks @@ -99,8 +99,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum if (ident.ToUpper() != "PZXT") { // this is not a valid TZX format file - throw new Exception(typeof(PzxConverter).ToString() + - "This is not a valid PZX format file"); + throw new Exception($"{nameof(PzxConverter)}: This is not a valid PZX format file"); } _position = 0; diff --git a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Tape/TAP/TapConverter.cs b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Tape/TAP/TapConverter.cs index 7e3906788f..dca42b861a 100644 --- a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Tape/TAP/TapConverter.cs +++ b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Tape/TAP/TapConverter.cs @@ -27,8 +27,8 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum /// public override bool IsWriter => false; - protected override Type SelfType - => typeof(TapConverter); + protected override string SelfTypeName + => nameof(TapConverter); private readonly DatacorderDevice _datacorder; diff --git a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Tape/TZX/TzxConverter.cs b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Tape/TZX/TzxConverter.cs index b3373509fb..9da1fd9a24 100644 --- a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Tape/TZX/TzxConverter.cs +++ b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Tape/TZX/TzxConverter.cs @@ -26,8 +26,8 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum /// public override bool IsWriter => false; - protected override Type SelfType - => typeof(TzxConverter); + protected override string SelfTypeName + => nameof(TzxConverter); /// /// Working list of generated tape data blocks @@ -205,8 +205,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum if (ident != "ZXTape!" || eotm != 0x1A) { // this is not a valid TZX format file - throw new Exception(typeof(TzxConverter) + - "This is not a valid TZX format file"); + throw new Exception($"{nameof(TzxConverter)}: This is not a valid TZX format file"); } // iterate through each block diff --git a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Tape/WAV/WavConverter.cs b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Tape/WAV/WavConverter.cs index aa6e13c2d2..9b9f8365fb 100644 --- a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Tape/WAV/WavConverter.cs +++ b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Tape/WAV/WavConverter.cs @@ -28,8 +28,8 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum /// public override bool IsWriter => false; - protected override Type SelfType - => typeof(WavConverter); + protected override string SelfTypeName + => nameof(WavConverter); /// /// Position counter @@ -77,8 +77,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum if (ident.ToUpper() != "WAVE") { // this is not a valid TZX format file - throw new Exception(typeof(WavConverter).ToString() + - "This is not a valid WAV format file"); + throw new Exception($"{nameof(WavConverter)}: This is not a valid WAV format file"); } //_position = 0; diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/QuickNES/QuickNES.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/QuickNES/QuickNES.cs index bb8c880487..651f999c11 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/QuickNES/QuickNES.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/QuickNES/QuickNES.cs @@ -293,7 +293,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES private void CheckDisposed() { if (Context == IntPtr.Zero) - throw new ObjectDisposedException(typeof(QuickNES).Name); + throw new ObjectDisposedException(nameof(QuickNES)); } // Fix some incorrect ines header entries that QuickNES uses to load games. diff --git a/src/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GenDbgHlp.cs b/src/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GenDbgHlp.cs index 6a326a70a0..0fc56a0c36 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GenDbgHlp.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GenDbgHlp.cs @@ -49,7 +49,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx public void SaveState(int statenum) { - if (disposed) throw new ObjectDisposedException(typeof(GenDbgHlp).ToString()); + if (disposed) throw new ObjectDisposedException(nameof(GenDbgHlp)); data[statenum] ??= new byte[length]; @@ -60,7 +60,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx public unsafe void Cmp(int statex, int statey) { - if (disposed) throw new ObjectDisposedException(typeof(GenDbgHlp).ToString()); + if (disposed) throw new ObjectDisposedException(nameof(GenDbgHlp)); List> bads = new List>(); byte[] x = data[statex]; @@ -134,7 +134,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx public List Find(IntPtr addr, int length) { - if (disposed) throw new ObjectDisposedException(typeof(GenDbgHlp).ToString()); + if (disposed) throw new ObjectDisposedException(nameof(GenDbgHlp)); Symbol min = new Symbol { addr = addr }; Symbol max = new Symbol { addr = addr + length };