как сгенерировать, если блок условия по CodeDOM или LinqExpression Dynamiclly? - PullRequest
2 голосов
/ 02 августа 2010
if ((x == 1 && y == "test") || str.Contains("test"))
  ...

как создать условие в блоке if с помощью CodeDOM или LinqExpression Dynamiclly с C #?

Ответы [ 2 ]

4 голосов
/ 09 апреля 2014

Чтобы позволить вам использовать чистый CodeDom для создания выражения, вы можете использовать CodeBinaryOperationExpression внутри CodeConditionStatement.

Условие будет выглядеть следующим образом:

CodeExpression condition = new CodeBinaryOperatorExpression(
    new CodeBinaryOperatorExpression(
        new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("x"), CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression(1)),
        CodeBinaryOperatorType.BooleanAnd,
        new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("y"), CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression("test"))),
    CodeBinaryOperatorType.BooleanOr,
    new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeVariableReferenceExpression("str"), "Contains"), new CodePrimitiveExpression("test")));

Тактогда все, что вам нужно, это истинные и, необязательно, ложные операторы:

CodeStatement[] trueStatements = { new CodeCommentStatement("Do this if true") };
CodeStatement[] falseStatements = { new CodeCommentStatement("Do this is false") };

Затем соедините все это в оператор if:

CodeConditionStatement ifStatement = new CodeConditionStatement(condition, trueStatements, falseStatements);

Полный пример созданиякласс с методом, который выполняет оценку, может выглядеть следующим образом:

CodeCompileUnit compileUnit = new CodeCompileUnit();
CodeNamespace exampleNamespace = new CodeNamespace("StackOverflow");
CodeTypeDeclaration exampleClass = new CodeTypeDeclaration("GeneratedClass");

CodeMemberMethod method = new CodeMemberMethod();
method.Attributes = MemberAttributes.Public | MemberAttributes.Final;
method.Name = "EvaluateCondition";
method.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(int)), "x"));
method.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(string)), "y"));
method.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(string)), "str"));

CodeExpression condition = new CodeBinaryOperatorExpression(
    new CodeBinaryOperatorExpression(
        new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("x"), CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression(1)),
        CodeBinaryOperatorType.BooleanAnd,
        new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("y"), CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression("test"))),
    CodeBinaryOperatorType.BooleanOr,
    new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeVariableReferenceExpression("str"), "Contains"), new CodePrimitiveExpression("test")));

CodeStatement[] trueStatements = { new CodeCommentStatement("Do this if true") };

CodeStatement[] falseStatements = { new CodeCommentStatement("Do this if false") };

CodeConditionStatement ifStatement = new CodeConditionStatement(condition, trueStatements, falseStatements);

method.Statements.Add(ifStatement);
exampleClass.Members.Add(method);
exampleNamespace.Types.Add(exampleClass);
compileUnit.Namespaces.Add(exampleNamespace);

Создать исходный вывод в C #, используя этот код ...

string sourceCode;
using (var provider = CodeDomProvider.CreateProvider("csharp"))
using (var stream = new MemoryStream())
using (TextWriter writer = new StreamWriter(stream))
using (IndentedTextWriter indentedWriter = new IndentedTextWriter(writer, "    "))
{
    provider.GenerateCodeFromCompileUnit(compileUnit, indentedWriter, new CodeGeneratorOptions()
    {
        BracingStyle = "C"
    });

    indentedWriter.Flush();

    stream.Seek(0, SeekOrigin.Begin);
    using (TextReader reader = new StreamReader(stream))
    {
        sourceCode = reader.ReadToEnd();
    }
}

... sourceCode будет содержать:

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.42000
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace StackOverflow
{


    public class GeneratedClass
    {

        public void EvaluateCondition(int x, string y, string str)
        {
            if ((((x == 1) 
                        && (y == "test")) 
                        || str.Contains("test")))
            {
                // Do this if true
            }
            else
            {
                // Do this if false
            }
        }
    }
}

Измените провайдера с csharp на vb, чтобы получить это:

'------------------------------------------------------------------------------
' <auto-generated>
'     This code was generated by a tool.
'     Runtime Version:4.0.30319.42000
'
'     Changes to this file may cause incorrect behavior and will be lost if
'     the code is regenerated.
' </auto-generated>
'------------------------------------------------------------------------------

Option Strict Off
Option Explicit On


Namespace StackOverflow

    Public Class GeneratedClass

        Public Sub EvaluateCondition(ByVal x As Integer, ByVal y As String, ByVal str As String)
            If (((x = 1)  _
                        AndAlso (y = "test"))  _
                        OrElse str.Contains("test")) Then
                'Do this if true
            Else
                'Do this if false
            End If
        End Sub
    End Class
End Namespace
1 голос
/ 29 марта 2011

Чтобы создать вышеупомянутый динамический код с использованием codedom, вам нужно сделать следующее:

Создать метод, который можно добавить в класс:

CodeMemberMethod method = new CodeMemberMethod();

method.Name = "TestMethod";
method.Attributes = MemberAttributes.Public | MemberAttributes.Final;

Создать команду If, включающую инструкциюнапример, внутри скобок {Value = 4;}:

CodeConditionStatement codeIf = new CodeConditionStatement(new
CodeSnippetExpression("(x == 1 && y == \"test\")|| str.Contains(\"test\")"), new 
            CodeSnippetStatement("value = 4;"));

Добавьте команду If к методу, который был создан выше:

method.Statements.Add(codeIf);
...