diff --git a/ICSharpCode.Decompiler/Metadata/MetadataExtensions.cs b/ICSharpCode.Decompiler/Metadata/MetadataExtensions.cs index e8612c4f1..7d8f06f34 100644 --- a/ICSharpCode.Decompiler/Metadata/MetadataExtensions.cs +++ b/ICSharpCode.Decompiler/Metadata/MetadataExtensions.cs @@ -152,6 +152,10 @@ namespace ICSharpCode.Decompiler.Metadata get => minimalCorlibTypeProvider; } + public static ISignatureTypeProvider MinimalSignatureTypeProvider { + get => minimalCorlibTypeProvider; + } + public static PrimitiveTypeCode ToPrimitiveTypeCode(this KnownTypeCode typeCode) { switch (typeCode) { diff --git a/ILSpy/Languages/CSharpLanguage.cs b/ILSpy/Languages/CSharpLanguage.cs index 9ecd38105..d157626dc 100644 --- a/ILSpy/Languages/CSharpLanguage.cs +++ b/ILSpy/Languages/CSharpLanguage.cs @@ -21,6 +21,7 @@ using System.Collections.Generic; using System.ComponentModel.Composition; using System.IO; using System.Linq; +using System.Reflection; using System.Reflection.Metadata; using System.Text; using System.Windows; @@ -562,22 +563,36 @@ namespace ICSharpCode.ILSpy var md = metadata.GetMethodDefinition((MethodDefinitionHandle)handle); declaringType = md.GetDeclaringType(); string methodName = metadata.GetString(md.Name); - if (methodName == ".ctor" || methodName == ".cctor") { - var td = metadata.GetTypeDefinition(declaringType); - methodName = ReflectionHelper.SplitTypeParameterCountFromReflectionName(metadata.GetString(td.Name)); - } else { - var genericParams = md.GetGenericParameters(); - if (genericParams.Count > 0) { - methodName += "<"; - int i = 0; - foreach (var h in genericParams) { - if (i > 0) - methodName += ","; - var gp = metadata.GetGenericParameter(h); - methodName += metadata.GetString(gp.Name); + switch (methodName) { + case ".ctor": + case ".cctor": + var td = metadata.GetTypeDefinition(declaringType); + methodName = ReflectionHelper.SplitTypeParameterCountFromReflectionName(metadata.GetString(td.Name)); + break; + case "Finalize": + const MethodAttributes finalizerAttributes = (MethodAttributes.Virtual | MethodAttributes.Family | MethodAttributes.HideBySig); + if ((md.Attributes & finalizerAttributes) != finalizerAttributes) + goto default; + MethodSignature methodSignature = md.DecodeSignature(MetadataExtensions.MinimalSignatureTypeProvider, default); + if (methodSignature.GenericParameterCount != 0 || methodSignature.ParameterTypes.Length != 0) + goto default; + td = metadata.GetTypeDefinition(declaringType); + methodName = "~" + ReflectionHelper.SplitTypeParameterCountFromReflectionName(metadata.GetString(td.Name)); + break; + default: + var genericParams = md.GetGenericParameters(); + if (genericParams.Count > 0) { + methodName += "<"; + int i = 0; + foreach (var h in genericParams) { + if (i > 0) + methodName += ","; + var gp = metadata.GetGenericParameter(h); + methodName += metadata.GetString(gp.Name); + } + methodName += ">"; } - methodName += ">"; - } + break; } if (fullName) return ToCSharpString(metadata, declaringType, fullName) + "." + methodName;