1
lambda表达式我想写像这样使用的CodeDOM:净CodeDom中 - .NET实现
.Where(x => x.Id == 2);
我不知道这个是什么在CodeDom中(System.CodeDom)的等价物。
lambda表达式我想写像这样使用的CodeDOM:净CodeDom中 - .NET实现
.Where(x => x.Id == 2);
我不知道这个是什么在CodeDom中(System.CodeDom)的等价物。
简答:CodeDOM不支持lambda表达式。
长答案:CodeDOM没有任何支持lambda表达式,所以你将不得不使用一种解决方法。一些选项:
使用CodeSnippetExpression
:
new CodeMethodInvokeExpression(
collectionExpression, "Where", new CodeSnippetExpression("x => x.Id == 2"));
这样,你就失去了大部分的使用的CodeDOM的优势,但它很容易,你可以做你想要什么。
创建从拉姆达含有代码的方法,然后使用委托引用它:
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)
这些问题与该方法的缺点是它产生不同(可读性较差)代码,如果查询必须是表达式,通常是因为您使用的是类似于Entity Framework的IQueryable<T>
,所以它不起作用。
切换到代码生成库支持lambda表达式,如罗斯林:
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))))
这里最明显的缺点是,你将不得不重写代码。
这个答案可能是你的情况http://stackoverflow.com/a/3273307/920557有用 –
的'X => x.Id == 2'被编译并传递给扩展的方法代表。在这种情况下'Func'请参阅https://msdn.microsoft.com/en-us/library/system.linq.enumerable.where(v=vs.110).aspx –
以下是CodeDom的表达式示例转换https://csharphardcoreprogramming.wordpress.com/2014/01/15/reflection-part-5-professional-codedom-lambda-expression-tree/ –