这里目的是为了将字符串转换为可执行的代码,同时将需要的参数传递到字符串中。做这个小例子的原因是想,因为存在部分经常改变的逻辑关系,所以想在前端搞成了可配置,同时又暂时不需要代码生成器进行生成。可配置的信息保存在数据库中,取用该数据的时候为代码进行。(因为前端现在没有配好,所以json 内部存在部分没有必要的字符串,为了临时使用,先忽视)
需要处理的字符串为
{“field1632462027268”:“TaskModel.C_Status”,“field1632462055053”:"",“field1632462079756”:“Unfinished”,“field1632462098476”:"&&",“field1632462108303”:“TaskRequestModel.C_Status”,“field1632462138052”:"",“field1632462153033”:“Unfinished”}
**
//这里是构建model ,并初始化传入数值
public class FourWayBusModel
{
public FourWayBusModel(string _ChargeStatus,int _Electricity)
{
C_ChargeStatus = _ChargeStatus;
C_Electricity = _Electricity;
}
public string C_ChargeStatus { get; set; }
public int C_Electricity { get; set; }
}
public class TaskModel
{
public TaskModel()
{
C_Status = "Unfinished";
}
public string C_Status { get; set; }
}
public class TaskRequestModel
{
public TaskRequestModel()
{
C_Status = "Unfinished";
}
public string C_Status { get; set; }
}
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.IO;
using System.Text;
using ConsoleApp4;
using Microsoft.CSharp;
class Program
{
public static void Main()
{
#region 模型赋值
FourWayBusModel FourWayBus = new FourWayBusModel("Charging", 21);
TaskModel taskModel = new TaskModel();
TaskRequestModel taskRequest = new TaskRequestModel();
#endregion
//需要记住要传入的模型
List<object> list = new List<object>();
list.Add(taskModel);
list.Add(taskRequest);
list.Add(FourWayBus);
//var from_model = new object[] { FourWayBus };
object[] vs2 = { };
string[] vscode = File.ReadAllLines(@"C:\Users\Administrator\Desktop\数据元数据.txt");
string code= AchieveString(ref vs2, list.ToArray(), vscode[0]);//传入空的object[] 和需要调用的模型以及抽取的字符串
//bool sdf = MyClass.PrintConsole("Charging", 96);
// object[] vs3 = {"Charging",96 };
//string value= AchieveString();
//传入到里面实参和构造好的字符串
bool resul = Meet_Condition(vs2, code);
Console.Read();
}
/// <summary>
/// 执行字符串中的条件
/// </summary>
/// <param name="vs">字符串中的实参</param>
/// <param name="code">字符串</param>
/// <returns>返回判断结果</returns>
public static bool Meet_Condition(object[] vs,string code)
{
// Compiler and CompilerParameters
CSharpCodeProvider codeProvider = new CSharpCodeProvider();
CompilerParameters compParameters = new CompilerParameters();
compParameters.GenerateInMemory = true;
string path = @"F:\value";
compParameters.TempFiles = new TempFileCollection(path);
// Compile the code
CompilerResults res = codeProvider.CompileAssemblyFromSource(compParameters, code);
//动态编译出错时
// if (res.Errors.HasErrors)
// {
// Exception ex = new Exception();
// ex.Data["code"] = code;
// throw ex;
// }
// else
// {
// // 编译后的程序集
// Assembly ass = res.CompiledAssembly;
Namespace是命名空间,Class是类名,赋值为需要的
// Type type = ass.GetType(string.Format("{0}.{1}", Namespace, Class));
// MethodInfo objectToString = type.GetMethod("ObjectToString");
// //动态执行的方法
// structToStringExecutor = new DynamicMethodExecutor(objectToString);
// }
// Create a new instance of the class 'MyClass' // 有命名空间的,需要命名空间.类名
object isRight = res.CompiledAssembly.CreateInstance("IsRight");
// Call the method 'PrintConsole' with the parameter 'Hello World'
// "Hello World" will be written in console
// new object[] { "Hello World" }
bool re= (bool)isRight.GetType().GetMethod("PrintConsole").Invoke(isRight, vs);
//Console.WriteLine(result);
return re;
}
/// <summary>
/// 拼接出条件
/// </summary>
/// <param name="vs2">字符串执行所需的实参</param>
/// <param name="from_model">需要使用的模型</param>
/// <returns>条件字符串 refc出vs2</returns>
public static string AchieveString(ref object[] vs2,object[] from_model,string string_FromSql)
{
//拼接成为字符串中的条件
StringBuilder builder_Condition = new StringBuilder();
//拼接成为字符串中的形参
StringBuilder builder_Files = new StringBuilder();
#region 对获得数据进行处理
string[] DealValue = string_FromSql.Split(new char[] { ':', '"', ',', '}', '{' });
//用来装载字段名称
string Empty_Box = string.Empty;
//这里list的主要用来保存实参,用来给字符串内部的判断传值
List<object> list = new List<object>();
foreach (var item in DealValue)
{
//如果是内部存在的field的数组需要被剔除 或者空的数组也要被排除
if (!item.Contains("field") && !string.IsNullOrEmpty(item) && item.Contains("."))
{
builder_Condition.Append(" ");
Empty_Box = item.Split('.')[1];
for (int i = 0; i < from_model.Length; i++)
{
if (item.Split('.')[0] == from_model[i].GetType().Name)
{ //判断该模型的相的字段是什么类型,如果是string则需要将模型取出的值转化为string类型
if (from_model[i].GetType().GetProperty(Empty_Box).PropertyType.ToString() == "System.String")
{
builder_Condition.Append(item.Split('.')[0]+ Empty_Box);
list.Add(from_model[i].GetType().GetProperty(Empty_Box).GetValue(from_model[i], null).ToString());
builder_Files.Append("string" + " " + item.Split('.')[0] + Empty_Box);
}
//判断该模型的相的字段是什么类型,如果是int则需要将模型取出的值转化为int类型
else if (from_model[i].GetType().GetProperty(Empty_Box).PropertyType.ToString() == "System.Int32")
{
builder_Condition.Append("Convert.ToInt32("+ item.Split('.')[0] + Empty_Box + ")");
list.Add(Convert.ToInt32(from_model[i].GetType().GetProperty(Empty_Box).GetValue(from_model[i], null)));
builder_Files.Append("int" + " " + item.Split('.')[0] + Empty_Box);
}
builder_Files.Append(",");
}
}
}
if (!item.Contains("field") && !string.IsNullOrEmpty(item) && !item.Contains("."))
{
builder_Condition.Append(" ");
if (item=="&&" ||item=="!=" ||item =="==" ||item=="||")
{
builder_Condition.Append(item);
}
else {
if (IsNumberic(item))
{
builder_Condition.Append(Convert.ToInt32(item));
}
else
{
builder_Condition.Append("\"" + item + "\"");
}
}
}
}
#endregion
//将实参整合成数组格式传递给VS2
vs2 = list.ToArray();
//截取形参的字符串将最后的“,”去掉
string String_parameter = builder_Files.ToString().Substring(0, builder_Files.ToString().Length-1);
//StringBuilder 将里面的内容转换为字符串
string re = builder_Condition.ToString();
//拼接成为字符串
string code = "using System; " +
"using System.IO; " +
"public class IsRight{ " +
" public static bool PrintConsole("+ String_parameter + "){ " +
"if(" + re + ")" +
"{return true; }" +
"return false;" +
" } " +
"} ";
return code;
}
/// <summary>
/// 判断字符串是否可以转化为数字
/// </summary>
/// <param name="str">要检查的字符串</param>
/// <returns>true:可以转换为数字;false:不是数字</returns>
public static bool IsNumberic(string str)
{
double vsNum;
bool isNum;
isNum = double.TryParse(str, System.Globalization.NumberStyles.Float,
System.Globalization.NumberFormatInfo.InvariantInfo, out vsNum);
return isNum;
}
}