diff --git a/ICSharpCode.Decompiler/Ast/Annotations.cs b/ICSharpCode.Decompiler/Ast/Annotations.cs index 7b22dd013..1c957292e 100644 --- a/ICSharpCode.Decompiler/Ast/Annotations.cs +++ b/ICSharpCode.Decompiler/Ast/Annotations.cs @@ -10,10 +10,12 @@ namespace ICSharpCode.Decompiler.Ast public class TypeInformation { public readonly TypeReference InferredType; + public readonly TypeReference ExpectedType; - public TypeInformation(TypeReference inferredType) + public TypeInformation(TypeReference inferredType, TypeReference expectedType) { this.InferredType = inferredType; + this.ExpectedType = expectedType; } } diff --git a/ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs b/ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs index 078fd4fa7..ce355bd26 100644 --- a/ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs +++ b/ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs @@ -262,7 +262,7 @@ namespace ICSharpCode.Decompiler.Ast result = node; if (result != null) - result = result.WithAnnotation(new TypeInformation(expr.InferredType)); + result = result.WithAnnotation(new TypeInformation(expr.InferredType, expr.ExpectedType)); if (result != null) return result.WithAnnotation(ilRanges); diff --git a/ICSharpCode.Decompiler/Ast/Transforms/DelegateConstruction.cs b/ICSharpCode.Decompiler/Ast/Transforms/DelegateConstruction.cs index 9c5aa97f6..5fc7d0d29 100644 --- a/ICSharpCode.Decompiler/Ast/Transforms/DelegateConstruction.cs +++ b/ICSharpCode.Decompiler/Ast/Transforms/DelegateConstruction.cs @@ -180,8 +180,8 @@ namespace ICSharpCode.Decompiler.Ast.Transforms foreach (AstNode node in body.Descendants) { if (node is ThisReferenceExpression) node.ReplaceWith(target.Clone()); - } + Expression replacement; if (isLambda) { LambdaExpression lambda = new LambdaExpression(); lambda.CopyAnnotationsFrom(ame); @@ -189,13 +189,32 @@ namespace ICSharpCode.Decompiler.Ast.Transforms Expression returnExpr = ((ReturnStatement)body.Statements.Single()).Expression; returnExpr.Remove(); lambda.Body = returnExpr; - objectCreateExpression.ReplaceWith(lambda); + replacement = lambda; } else { ame.Body = body; - objectCreateExpression.ReplaceWith(ame); + replacement = ame; + } + var expectedType = objectCreateExpression.Annotation().ExpectedType.Resolve(); + if (expectedType != null && !IsDelegate(expectedType)) { + var simplifiedDelegateCreation = (ObjectCreateExpression)objectCreateExpression.Clone(); + simplifiedDelegateCreation.Arguments.Clear(); + simplifiedDelegateCreation.Arguments.Add(replacement); + replacement = simplifiedDelegateCreation; } + objectCreateExpression.ReplaceWith(replacement); return true; } + + static bool IsDelegate(TypeDefinition type) + { + if (type.BaseType != null && type.BaseType.Namespace == "System") { + if (type.BaseType.Name == "MulticastDelegate") + return true; + if (type.BaseType.Name == "Delegate" && type.Name != "MulticastDelegate") + return true; + } + return false; + } internal static bool IsPotentialClosure(DecompilerContext context, TypeDefinition potentialDisplayClass) {