如何通过CodeDOM或LinqExpression动态生成if条件块?

发布于 2024-09-12 15:34:51 字数 150 浏览 1 评论 0原文

if ((x == 1 && y == "test") || str.Contains("test"))
  ...

如何使用 C# 通过 CodeDOM 或 LinqExpression 动态生成 if 块中的条件?

if ((x == 1 && y == "test") || str.Contains("test"))
  ...

how to generate condition in the if block by CodeDOM or LinqExpression Dynamiclly with C#?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我一直都在从未离去 2024-09-19 15:34:51

要允许您使用纯 CodeDom 创建表达式,您可以在 CodeConditionStatement 内使用 CodeBinaryOperationExpression

条件如下所示:

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

那么您所需要的就是 true 和 false 语句:

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

To allow you to use pure CodeDom for creating the expression you can use the CodeBinaryOperationExpression inside the CodeConditionStatement.

The condition would look like this:

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

So then all you need are the true, and optionally false, statements:

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

Then put it all together in the if statement:

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

The complete sample to create a class with a method that performs the evaluation could look like this:

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

Generate source output in C# using this code...

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 will contain:

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

Change the provider from csharp to vb to get this:

'------------------------------------------------------------------------------
' <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
肥爪爪 2024-09-19 15:34:51

要使用 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);

To create the code above dynamical using codedom you need to do the following:

Create a Method which can be added to a class:

CodeMemberMethod method = new CodeMemberMethod();

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

Create a If command including statement inside the brackets eg {Value = 4;}:

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

Add the If command to the method which was created above:

method.Statements.Add(codeIf);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文