根据数据库记录动态生成C#类及其公共属性并动态执行的解决方案

问题:

C#中,想动态产生这么一个类:

public class StatisticsData
    {
        public string order_no { get; set; }
        public int qty { get; set; }

        public int ocv1_plan { get; set; }
        public int ocv1_A { get; set; }
        public int ocv1_Ba { get; set; }
        // ....
        public int ocv2_plan { get; set; }
        public int ocv2_A { get; set; }
        public int ocv2_B { get; set; }
        // ....
        public int ocv2_N { get; set; }

        public int ocv3_plan { get; set; }
        public int ocv3_A { get; set; }
        // ....
        public int ocv3_X { get; set; }
        public int ocv4_plan { get; set; }
        public int ocv4_A { get; set; }
        // ....
        public int ocv4_T { get; set; }
// ....
      }
需要用代码动态生成,因为上面的ocv1,2...以及Rank等级都是从数据库中取记录,有什么样的记录,有多少条记录,不确定,因此需要动态生成。
其中部分公共属性是固定的,而另一部分则是动态的,比如:ocv数字_xxx。
可能有多个不定的ocv数字及_xxx,分别根据一个List<string> listOcv(工序列表)和一个Dictionary<string, string[]> dictRank(等级列表)得到:
List<string> listOcv = new List<string>();
listOcv.Add("ocv1");
listOcv.Add("ocv2");
listOcv.Add("ocv3");
listOcv.Add("ocv4");
//...
Dictionary<string, string[]> dictRank=new Dictionary<string, string[]>();
dictRank.Add("ocv1", new string[]{"plan","A","Ba"});
dictRank.Add("ocv2", new string[]{"plan","A","B", ..., "N"});
dictRank.Add("ocv3", new string[]{"plan","A", ..., "X"});

dictRank.Add("ocv4", new string[]{"plan","A", ..., "T"});

思考其解决方案,提示:用DynamicObject 类继承或.net反射。


发布了399 篇原创文章 · 获赞 223 · 访问量 360万+
展开阅读全文

C#动态生成的问题,取得程序集出了问题

07-28

需求就是在unity中,解析一个Excel文件,根据解析到的信息动态生成类,并将数据存入(一个继承ScriptableOjbect类的对象里,这里具体记不清了) 前面解析Excel好像都没什么问题,类的源码信息存到了classSource里,尝试过输出到txt里面看过,所输出的类结构没有问题。 问题出在后面的编译代码和获取编译后的程序集,unity报错“NullReferenceException: Object reference not set to an instance of an object DynamicClass.setCode () (at Assets/Scripts/DynamicClass.cs:80) DynamicClass.Start () (at Assets/Scripts/DynamicClass.cs:92) 动态创建类是参考http://www.cnblogs.com/firstyi/archive/2008/03/07/1094652.html这里的 新手希望能解答一下,谢谢。 ``` //ExcelData.cs 存储从Excel解析来的类信息和数据 using System.Collections; using System.Collections.Generic; using UnityEngine; public class ExcelData : ScriptableObject { [SerializeField] public struct classVar { public string varName; public string varType; }; public string _className; public List<classVar> _variable; public List<List<int>> _data; } ``` ``` //ExcelManager.cs 解析Excel文件 using System.Collections; using System.Collections.Generic; using UnityEngine; using NPOI.SS.UserModel; using NPOI.HSSF.UserModel; using NPOI.XSSF.UserModel; using System.IO; using UnityEngine.UI; public class ExcelManager { public static ExcelManager _instance = null; public static ExcelManager Instance { get { if (null == _instance) return new ExcelManager(); else return _instance; } } public int _invalidRow = 0; public int _dataIndex = -1; public ExcelData ReadExcel() { ExcelData excelData = ScriptableObject.CreateInstance<ExcelData>(); excelData._variable = new List<ExcelData.classVar>(); excelData._data = new List<List<int>>(); //测试 string fileName = "/Users/lijiesheng/Desktop/test.xlsx"; IWorkbook workbook = null; FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read); if (fileName.IndexOf(".xlsx") > 0) { //2007版 workbook = new XSSFWorkbook(fileStream); } else if (fileName.IndexOf(".xls") > 0) { //2003版 workbook = new HSSFWorkbook(fileStream); } else { Debug.LogError("File is not existed."); } ISheet sheet = workbook.GetSheetAt(0); excelData._className = sheet.SheetName; excelData._className = excelData._className.Substring(1, excelData._className.Length - 1); IRow row; for (int i = 0; i < sheet.LastRowNum; ++i) { row = sheet.GetRow(i); if (row != null) { //若该行首列内容以'#'开头,则跳过该行 string tmp = row.GetCell(0).ToString(); if (tmp[0] == '#') { ++_invalidRow; continue; } for (int j = 0; j < row.LastCellNum; ++j) { string cellValue = row.GetCell(j).ToString(); if (cellValue[0] == '&') { //内容以'&'开头则记录变量名和类型 int index = cellValue.IndexOf('|'); string tmpVarName = cellValue.Substring(1, index - 1); tmpVarName.ToLower(); string tmpVarType = cellValue.Substring(index + 1, cellValue.Length - (index + 1)); tmpVarName.ToLower(); ExcelData.classVar cv; cv.varName = tmpVarName; cv.varType = tmpVarType; excelData._variable.Add(cv); } else { //否则记录数据 if (excelData._data.Count <= i - _invalidRow) { ++_dataIndex; excelData._data.Add(new List<int>()); //_data[_dataIndex] = new List<int>(); excelData._data[_dataIndex].Add(int.Parse(cellValue)); } else { excelData._data[_dataIndex].Add(int.Parse(cellValue)); } } } } } fileStream.Close(); workbook.Close(); return excelData; ////测试 //Debug.Log(excelData._className); //foreach(var pair in excelData._variable) //{ // Debug.Log(pair.varName + " " + pair.varType); //} //for (int i = 0; i < excelData._data.Count; ++i) //{ // Debug.Log("_data.Count" + i + " " + excelData._data[i].Count); // for (int j = 0; j < excelData._data[i].Count; ++j) // { // Debug.Log(excelData._data[i][j]); // } //} } } ``` ``` //DynamicClass.cs 动态创建类 using System.Collections; using System.Collections.Generic; using System.Text; using UnityEngine; using Microsoft.CSharp; using System.CodeDom.Compiler; using System.Reflection; using System.CodeDom; using System; using System.IO; using UnityEditor; public class DynamicClass : MonoBehaviour { ExcelData _excelData; public Assembly _assembly; //创建编译器实例 public CSharpCodeProvider provider; //设置编译参数 public CompilerParameters paras; public static StringBuilder _classSource; public void getData() { _excelData = ExcelManager.Instance.ReadExcel(); } //动态创建类 public Assembly NewAssembly(string classSource) { provider = new CSharpCodeProvider(); paras = new CompilerParameters(); paras.GenerateExecutable = false; paras.GenerateInMemory = true; paras.OutputAssembly = "/Users/lijiesheng/Desktop/" + _excelData._className + ".dll"; //编译代码 CompilerResults result = provider.CompileAssemblyFromSource(paras, classSource); //获取编译后的程序集 Assembly assembly = result.CompiledAssembly; return assembly; } //[MenuItem("Tools/Generate Class")] public void SetCode() { getData(); _classSource = new StringBuilder(); _classSource.Append("using System;\n"); _classSource.Append("using UnityEngine;\n"); _classSource.Append("using System.Collections;\n"); _classSource.Append("using System.Collections.Generic;\n\n"); _classSource.Append("[Serializable]\n"); _classSource.Append("public class " + _excelData._className +"\n"); _classSource.Append("{\n"); foreach (var pair in _excelData._variable) { _classSource.Append(" public " + pair.varType + " " + pair.varName + ";\n"); //Debug.Log(pair.varType + " " + pair.varName); } _classSource.Append("}\n"); //验证文本 FileStream fs = new FileStream("/Users/lijiesheng/Desktop/test.txt", FileMode.Create); byte[] data = System.Text.Encoding.Default.GetBytes(_classSource.ToString()); fs.Write(data, 0, data.Length); fs.Flush(); fs.Close(); _assembly = NewAssembly(_classSource.ToString()); ////---TODO--- //object generatedClass = _assembly.CreateInstance(_excelData._className); //PropertyInfo[] infos = generatedClass.GetType().GetProperties(); //foreach (var info in infos) //{ // Debug.Log(info.Name); //} } void Start() { SetCode(); } } ``` 工程文件:链接: https://pan.baidu.com/s/1ylpOGiaPTT0gIKsMD39b7A 密码: hxw5 不知道在哪里上传附件,就放盘里了。希望大佬们帮忙解答一下,非常感谢。 问答

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览