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

CodeDOMまたはLinqExpressionDynamicllywith C#によってifブロックで条件を生成する方法は?

4

2 に答える 2

4

式を作成するために純粋な 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")));

したがって、必要なのは 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
于 2014-04-09T11:04:47.983 に答える
1

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);
于 2011-03-29T13:34:36.507 に答える