2017-04-27 38 views
1

lambda表達式我想寫像這樣使用的CodeDOM:淨CodeDom中 - .NET實現

.Where(x => x.Id == 2); 

我不知道這個是什麼在CodeDom中(System.CodeDom)的等價物。

+1

這個答案可能是你的情況http://stackoverflow.com/a/3273307/920557有用 –

+1

的'X => x.Id == 2'被編譯並傳遞給擴展的方法代表。在這種情況下'Func '請參閱https://msdn.microsoft.com/en-us/library/system.linq.enumerable.where(v=vs.110).aspx –

+0

以下是CodeDom的表達式示例轉換https://csharphardcoreprogramming.wordpress.com/2014/01/15/reflection-part-5-professional-codedom-lambda-expression-tree/ –

回答

3

簡答:CodeDOM不支持lambda表達式。

長答案:CodeDOM沒有任何支持lambda表達式,所以你將不得不使用一種解決方法。一些選項:

  1. 使用CodeSnippetExpression

    new CodeMethodInvokeExpression(
        collectionExpression, "Where", new CodeSnippetExpression("x => x.Id == 2")); 
    

    這樣,你就失去了大部分的使用的CodeDOM的優勢,但它很容易,你可以做你想要什麼。

  2. 創建從拉姆達含有代碼的方法,然後使用委託引用它:

    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>,所以它不起作用。

  3. 切換到代碼生成庫支持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)))) 
    

    這裏最明顯的缺點是,你將不得不重寫代碼。