2017-04-27 1 views
1

에서 람다 식을 구현 나는이 사용 된 CodeDom 같은 것을 쓰고 싶어요.닷넷 된 CodeDom은 .NET

+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

다음은 Expression to CodeDom의 예제입니다 전환 https://csharphardcoreprogramming.wordpress.com/2014/01/15/reflection-part-5-professional-codedom-lambda-expression-tree/ –

답변

3

짧은 대답 : CodeDOM은 람다를 지원하지 않습니다.

긴 답변 : CodeDOM은 람다를 지원하지 않으므로 해결 방법을 사용해야합니다. 일부 옵션 :

  1. 사용 CodeSnippetExpression :

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

    이 방법을 사용하면 된 CodeDom 사용의 장점의 대부분을 잃게하지만, 쉽게 그리고 당신은 정확하게 당신이 원하는 것을 할 수 있습니다.

  2. 를 참조하는 대리자를 사용하여 다음 람다에서 코드를 포함하는 방법을 만들고 :이 방법으로

    private void IsIdTwo(YourEntityType x) { 
        return (x.Id == 2); 
    } 
    
    … 
    
    collection.Where(IsIdTwo) 
    

    이슈가 다른 생성하는되어

    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")) 
    

    이 코드 등이 생성 일반적으로 사용자가 IQueryable<T>을 Entity Framework와 같이 사용하고 있기 때문에 쿼리를 표현식으로 사용해야하는 경우 원하는 코드보다 읽기 쉽고 읽기 쉬운 코드가 필요하지 않습니다. 로슬린처럼, 람다를 지원하는 코드 생성 라이브러리

  3. 스위치 :

    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)))) 
    

    여기 명백한 단점은 당신이 당신의 코드를 다시 작성해야 할 것입니다.