if ((x == 1 && y == "test") || str.Contains("test"))
...
如何用CodeDOM或LinqExpression动态地用C#在if块中生成条件?
答案 0 :(得分: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")));
那么你需要的只是真实的,可选的假的陈述:
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 :(得分: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);