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/ –