public TableFileRow NewRow() { int rowId = TabFile.Rows.Count + 1; var newRow = new TableFileRow(rowId, TabFile.Headers); TabFile.Rows.Add(rowId, newRow); return(newRow); }
//internal PropertyInfo[] TabProperties //{ // get // { // List<PropertyInfo> props = new List<PropertyInfo>(); // foreach (var fieldInfo in typeof(T).GetProperties()) // { // if (fieldInfo.GetCustomAttributes(typeof(TabColumnAttribute), true).Length > 0) // { // props.Add(fieldInfo); // } // } // return props.ToArray(); // } //} /// <summary> /// Auto parser with class's definition fields (poor performance warning) /// </summary> /// <param name="tableRow"></param> /// <param name="cellStrs"></param> protected void AutoParse(TableFileRow tableRow, string[] cellStrs) { var type = tableRow.GetType(); var okFields = new List <FieldInfo>(); //解析field foreach (FieldInfo field in AutoTabFields) { if (!HasColumn(field.Name)) { OnException(TableFileExceptionType.NotFoundHeader, type.Name, field.Name); continue; } okFields.Add(field); } foreach (var field in okFields) { var fieldName = field.Name; var fieldType = field.FieldType; //通过TableRowFieldParser自动解析string to fieldType var methodName = string.Format("Get_{0}", fieldType.Name); var method = type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.NonPublic); if (method != null) { // 找寻FieldName所在索引 int index = Headers[fieldName].ColumnIndex; // default value //string szType = "string"; string defaultValue = ""; var headerDef = Headers[fieldName].HeaderMeta; if (!string.IsNullOrEmpty(headerDef)) { var defs = headerDef.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); //if (defs.Length >= 1) szType = defs[0]; if (defs.Length >= 2) { defaultValue = defs[1]; } } field.SetValue(tableRow, method.Invoke(tableRow, new object[] { cellStrs[index], defaultValue })); } else { OnException(TableFileExceptionType.NotFoundGetMethod, methodName); } } }
//internal PropertyInfo[] TabProperties //{ // get // { // List<PropertyInfo> props = new List<PropertyInfo>(); // foreach (var fieldInfo in typeof(T).GetProperties()) // { // if (fieldInfo.GetCustomAttributes(typeof(TabColumnAttribute), true).Length > 0) // { // props.Add(fieldInfo); // } // } // return props.ToArray(); // } //} //解析TableFileRow类的所有成员。将cellStrs数据反射保存到TableFileRow protected void AutoParse(TableFileRow tableRow, string[] cellStrs) { var type = tableRow.GetType(); var okFields = new List <FieldInfo>(); //遍历TableFileRow的所有成员,容错 foreach (FieldInfo field in AutoTabFields) { if (!HasColumn(field.Name)) { //类中没有这个成员名称,报错 OnException(TableFileExceptionType.NotFoundHeader, type.Name, field.Name); continue; } okFields.Add(field); } //遍历所有成员 foreach (var field in okFields) { //成员名称 var fieldName = field.Name; var fieldType = field.FieldType; //判断该成员是否有Get方法 var methodName = string.Format("Get_{0}", fieldType.Name); var method = type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.NonPublic); if (method != null) { //有Get方法 // FieldName所在索引 int index = Headers[fieldName].ColumnIndex; //该成员默认值。如果第二行的声明,根据,分割后有两项,则第一项是默认值 string defaultValue = ""; var headerDef = Headers[fieldName].HeaderMeta; if (!string.IsNullOrEmpty(headerDef)) { var defs = headerDef.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); //if (defs.Length >= 1) szType = defs[0]; if (defs.Length >= 2) { defaultValue = defs[1]; } } //调用TableFileRow的Get方法,数据保存 field.SetValue(tableRow, method.Invoke(tableRow, new object[] { //数据 cellStrs[index], defaultValue })); } else { //没有Get方法,报错 OnException(TableFileExceptionType.NotFoundGetMethod, methodName); } } }
private int _rowIndex = 1; // 从第1行开始 protected bool ParseReader(TextReader oReader) { // 首行 var headLine = oReader.ReadLine(); if (headLine == null) { OnException(TableFileExceptionType.HeadLineNull); return(false); } var metaLine = oReader.ReadLine(); // 声明行 if (metaLine == null) { OnException(TableFileExceptionType.MetaLineNull); return(false); } string[] firstLineSplitString = headLine.Split(_config.Separators, StringSplitOptions.None); // don't remove RemoveEmptyEntries! string[] firstLineDef = new string[firstLineSplitString.Length]; var metaLineArr = metaLine.Split(_config.Separators, StringSplitOptions.None); Array.Copy(metaLineArr, 0, firstLineDef, 0, metaLineArr.Length); // 拷贝,确保不会超出表头的 for (int i = 0; i < firstLineSplitString.Length; i++) { var headerString = firstLineSplitString[i]; var headerInfo = new HeaderInfo { ColumnIndex = i, HeaderName = headerString, HeaderMeta = firstLineDef[i], }; Headers[headerInfo.HeaderName] = headerInfo; } _colCount = firstLineSplitString.Length; // 標題 // 读取行内容 string sLine = ""; while (sLine != null) { sLine = oReader.ReadLine(); if (sLine != null) { string[] splitString1 = sLine.Split(_config.Separators, StringSplitOptions.None); TabInfo[_rowIndex] = splitString1; //新建行对象 T newT = new T();// prevent IL2CPP stripping! //储存行数和头信息到行对象中 newT.Ctor(_rowIndex, Headers); // the New Object may not be used this time, so cache it! //储存行内容 newT.Values = splitString1; if (!newT.IsAutoParse) { newT.Parse(splitString1); } else { AutoParse(newT, splitString1); } if (newT.GetPrimaryKey() != null) { TableFileRow oldT; if (!PrimaryKey2Row.TryGetValue(newT.GetPrimaryKey(), out oldT)) // 原本不存在,使用new的,释放cacheNew,下次直接new { PrimaryKey2Row[newT.GetPrimaryKey()] = newT; } else // 原本存在,使用old的, cachedNewObj(newT)因此残留, 留待下回合使用 { TableFileRow toT = oldT; // Check Duplicated Primary Key, 使用原来的,不使用新new出来的, 下回合直接用_cachedNewObj OnException(TableFileExceptionType.DuplicatedKey, toT.GetPrimaryKey().ToString()); newT = (T)toT; } } Rows[_rowIndex] = newT; _rowIndex++; } } return(true); }
protected bool ParseReader(TextReader oReader) { //1. 首行。每一项保存到HeaderInfo.HeaderName var headLine = oReader.ReadLine(); if (headLine == null) { OnException(TableFileExceptionType.HeadLineNull); return(false); } //2. 声明行。每一项保存到HeaderInfo.HeaderMeta var metaLine = oReader.ReadLine(); if (metaLine == null) { OnException(TableFileExceptionType.MetaLineNull); return(false); } //首行是每一项的名称,先读取到HeaderInfo string[] firstLineSplitString = headLine.Split(_config.Separators, StringSplitOptions.None); // don't remove RemoveEmptyEntries! string[] firstLineDef = new string[firstLineSplitString.Length]; //将声明行的数据拷贝firstLineDef,确保不会超出表头的。再赋值给HeaderInfo var metaLineArr = metaLine.Split(_config.Separators, StringSplitOptions.None); Array.Copy(metaLineArr, 0, firstLineDef, 0, metaLineArr.Length); for (int i = 0; i < firstLineSplitString.Length; i++) { var headerString = firstLineSplitString[i]; //创建一个HeaderInfo var headerInfo = new HeaderInfo { ColumnIndex = i, HeaderName = headerString, HeaderMeta = firstLineDef[i], }; Headers[headerInfo.HeaderName] = headerInfo; } //列数 _colCount = firstLineSplitString.Length; //3. 剩余的行内容,创建TableFileRow来保存 string sLine = ""; while (sLine != null) { sLine = oReader.ReadLine(); if (sLine != null) { string[] splitString1 = sLine.Split(_config.Separators, StringSplitOptions.None); TabInfo[_rowIndex] = splitString1; //创建一行的数据TableFileRow T newT = new T(); newT.Ctor(_rowIndex, Headers); newT.Values = splitString1; if (!newT.IsAutoParse) { //非自动解析 newT.Parse(splitString1); } else { //自动解析,反射,赋值给TableFileRow AutoParse(newT, splitString1); } if (newT.GetPrimaryKey() != null) { TableFileRow oldT; if (!PrimaryKey2Row.TryGetValue(newT.GetPrimaryKey(), out oldT)) { // 原本不存在,使用new的,释放cacheNew,下次直接new PrimaryKey2Row[newT.GetPrimaryKey()] = newT; } else { // 原本存在,说明表里有多个PrimaryKey,报个错 TableFileRow toT = oldT; OnException(TableFileExceptionType.DuplicatedKey, toT.GetPrimaryKey().ToString()); // 使用原来的,不使用新new出来的, 下回合直接用_cachedNewObj newT = (T)toT; } } //TableFileRow保存到Rows Rows[_rowIndex] = newT; _rowIndex++; } } return(true); }