我想使用CodeDom编写如下内容:
.Where(x => x.Id == 2);
Run Code Online (Sandbox Code Playgroud)
我不知道CodeDom(System.CodeDom)中的等效功能。
简短答案:CodeDOM不支持lambda。
长答案:CodeDOM不支持lambda,因此您必须使用一种解决方法。一些选项:
用途CodeSnippetExpression:
new CodeMethodInvokeExpression(
collectionExpression, "Where", new CodeSnippetExpression("x => x.Id == 2"));
Run Code Online (Sandbox Code Playgroud)
这样,您将失去使用CodeDOM的大部分优势,但是这很容易,并且可以完全按照自己的意愿进行操作。
创建一个包含来自lambda的代码的方法,然后使用引用它的委托:
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"))
Run Code Online (Sandbox Code Playgroud)
这将生成如下代码:
private void IsIdTwo(YourEntityType x) {
return (x.Id == 2);
}
…
collection.Where(IsIdTwo)
Run Code Online (Sandbox Code Playgroud)
这种方法的问题在于,它生成的代码与您想要的代码不同(且可读性更差),并且如果查询必须是表达式,则该代码将不起作用,通常是因为您使用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))))))))
Run Code Online (Sandbox Code Playgroud)
或使用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))))
Run Code Online (Sandbox Code Playgroud)
这里明显的缺点是您将不得不重写代码。
| 归档时间: |
|
| 查看次数: |
571 次 |
| 最近记录: |