diff --git a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs index 73a72f3a4..7c281d339 100644 --- a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs @@ -1014,9 +1014,28 @@ namespace ICSharpCode.Decompiler.CSharp rr = new CSharpInvocationResolveResult(target.ResolveResult, method, argumentResolveResults); if (inst.OpCode == OpCode.NewObj) { - var argumentExpressions = arguments.Select(arg => arg.Expression); - return new ObjectCreateExpression(ConvertType(inst.Method.DeclaringType), argumentExpressions) - .WithILInstruction(inst).WithRR(rr); + var argumentExpressions = arguments.SelectArray(arg => arg.Expression); + if (method.DeclaringType.IsAnonymousType()) { + AnonymousTypeCreateExpression atce = new AnonymousTypeCreateExpression(); + var parameters = inst.Method.Parameters; + if (CanInferAnonymousTypePropertyNamesFromArguments(argumentExpressions, parameters)) { + atce.Initializers.AddRange(argumentExpressions); + } else { + for (int i = 0; i < argumentExpressions.Length; i++) { + atce.Initializers.Add( + new NamedExpression { + Name = parameters[i].Name, + Expression = argumentExpressions[i] + }); + } + } + return atce + .WithILInstruction(inst) + .WithRR(rr); + } else { + return new ObjectCreateExpression(ConvertType(inst.Method.DeclaringType), argumentExpressions) + .WithILInstruction(inst).WithRR(rr); + } } else { Expression expr; int allowedParamCount = (method.ReturnType.IsKnownType(KnownTypeCode.Void) ? 1 : 0); @@ -1051,6 +1070,24 @@ namespace ICSharpCode.Decompiler.CSharp } } + static bool CanInferAnonymousTypePropertyNamesFromArguments(IList args, IList parameters) + { + for (int i = 0; i < args.Count; i++) { + string inferredName; + if (args[i] is IdentifierExpression) + inferredName = ((IdentifierExpression)args[i]).Identifier; + else if (args[i] is MemberReferenceExpression) + inferredName = ((MemberReferenceExpression)args[i]).MemberName; + else + inferredName = null; + + if (inferredName != parameters[i].Name) { + return false; + } + } + return true; + } + Expression HandleAccessorCall(ILInstruction inst, TranslatedExpression target, IMethod method, IList arguments) { var lookup = new MemberLookup(resolver.CurrentTypeDefinition, resolver.CurrentTypeDefinition.ParentAssembly); diff --git a/ICSharpCode.Decompiler/CSharp/Transforms/DeclareVariables.cs b/ICSharpCode.Decompiler/CSharp/Transforms/DeclareVariables.cs index da2588466..2901da3c8 100644 --- a/ICSharpCode.Decompiler/CSharp/Transforms/DeclareVariables.cs +++ b/ICSharpCode.Decompiler/CSharp/Transforms/DeclareVariables.cs @@ -255,11 +255,14 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms if (v.RemovedDueToCollision) continue; - AstType type = context.TypeSystemAstBuilder.ConvertType(v.Type); - var boe = (v.InsertionPoint.nextNode as ExpressionStatement)?.Expression as AssignmentExpression; if (boe != null && boe.Left.IsMatch(new IdentifierExpression(v.Name))) { - + AstType type; + if (v.Type.ContainsAnonymousType()) { + type = new SimpleType("var"); + } else { + type = context.TypeSystemAstBuilder.ConvertType(v.Type); + } var vds = new VariableDeclarationStatement(type, v.Name, boe.Right.Detach()); var init = vds.Variables.Single(); init.AddAnnotation(boe.Left.GetResolveResult()); @@ -271,6 +274,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms replacements.Add(new KeyValuePair(v.InsertionPoint.nextNode, vds)); } else { Expression initializer = null; + AstType type = context.TypeSystemAstBuilder.ConvertType(v.Type); if (v.DefaultInitialization) { initializer = new DefaultValueExpression(type.Clone()); }