if ((x == 1 && y == "test") || str.Contains("test"))
...
how to generate condition in the if block by CodeDOM or LinqExpression Dynamiclly with C#?
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
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);
来源:https://stackoverflow.com/questions/3388610/how-to-generate-if-condition-block-by-codedom-or-linqexpression-dynamiclly