我想使用 CodeDom 编写这样的内容:
.Where(x => x.Id == 2);
我不知道 CodeDom (System.CodeDom) 中与此等效的是什么。
最佳答案
简短回答:CodeDOM 不支持 lambda。
长答案:CodeDOM 不支持 lambda,因此您必须使用解决方法。一些选项:
使用
CodeSnippetExpression
:new CodeMethodInvokeExpression( collectionExpression, "Where", new CodeSnippetExpression("x => x.Id == 2"));
这样,您就失去了使用 CodeDOM 的大部分优势,但它很简单,您可以做您想做的事情。
创建一个包含 lambda 代码的方法,然后使用引用它的委托(delegate):
var lambdaMethod = new CodeMemberMethod { Name = "IsIdTwo", Parameters = { new CodeParameterDeclarationExpression( new CodeTypeReference("YourEntityType"), "x") }, Statements = { new CodeMethodReturnStatement( new CodeBinaryOperatorExpression( new CodePropertyReferenceExpression( new CodeVariableReferenceExpression("x"), "Id"), CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression(2))) } }; … new CodeMethodInvokeExpression( collectionExpression, "Where", new CodeMethodReferenceExpression(null, "IsIdTwo"))
这会生成如下代码:
private void IsIdTwo(YourEntityType x) { return (x.Id == 2); } … collection.Where(IsIdTwo)
这种方法的问题在于,它会生成与您想要的不同(且可读性较差)的代码,并且如果查询必须是表达式,则它将无法工作,通常是因为您使用的是
IQueryable<T>
使用 Entity Framework 之类的东西。切换到支持 lambda 的代码生成库,例如 Roslyn:
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory; … InvocationExpression( MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, IdentifierName("collection"), IdentifierName("Where")), ArgumentList( SingletonSeparatedList( Argument( SimpleLambdaExpression( Parameter(Identifier("x")), BinaryExpression( SyntaxKind.EqualsExpression, MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, IdentifierName("x"), IdentifierName("Id")), LiteralExpression( SyntaxKind.NumericLiteralExpression, Literal(2))))))))
或者使用
SyntaxGenerator
:var generator = SyntaxGenerator.GetGenerator(new AdhocWorkspace(), LanguageNames.CSharp); generator.InvocationExpression( generator.MemberAccessExpression(generator.IdentifierName("collection"), "Where"), generator.ValueReturningLambdaExpression( "x", generator.ValueEqualsExpression( generator.MemberAccessExpression(generator.IdentifierName("x"), "Id"), generator.LiteralExpression(2))))
这里明显的缺点是您必须重写代码。
关于c# - .Net CodeDom - 在 .net 中实现 lambda 表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43658351/