writer.WriteLine("// 從資料讀取器讀取資料建立物件");
writer.WriteLine("protected override object InnerReadRecord(IDataReader reader, int[] FieldIndexs)");
writer.BeginGroup("{");
writer.WriteLine($"{recordType.FullName} record = new {recordType.FullName}();");
writer.WriteLine("int index = 0;");
for (int i = 0; i < ps.Length; i++)
{
PropertyInfo p = ps[i];
if (!p.CanWrite) continue;
var attr = (BindFieldAttribute)Attribute.GetCustomAttribute(p, typeof(BindFieldAttribute));
writer.WriteLine("");
writer.WriteLine($"index = FieldIndexs[{i}]; // 讀取欄位 {GetBindFieldName(p)}");
writer.WriteLine("if (index >= 0)");
writer.BeginGroup("{");
Type pt = p.PropertyType;
object defVal = GetDefaultValue(p);
string readExpr = null;
if (pt == typeof(byte))
readExpr = $"ConvertToByte(reader.GetValue(index), {GetValueString(pt, defVal)})";
else if (pt == typeof(sbyte))
readExpr = $"ConvertToSByte(reader.GetValue(index), {GetValueString(pt, defVal)})";
else if (pt == typeof(short))
readExpr = $"ConvertToInt16(reader.GetValue(index), {GetValueString(pt, defVal)})";
// ... 其他基本型別 ConvertToXxx
else if (pt == typeof(DateTime))
{
string defStr = "DateTime.MinValue";
DateTime dt = Convert.ToDateTime(defVal);
if (dt != DateTime.MinValue) defStr = $"new DateTime({dt.Ticks})";
readExpr = $"ConvertToDateTime(reader.GetValue(index), {defStr}, {attr.ReadFormat == null ? "null" : $"\"{attr.ReadFormat}\""})";
}
else if (pt == typeof(string))
readExpr = $"ConvertToString(reader.GetValue(index), {defVal == null ? "null" : $"@\"{defVal}\""})";
else if (pt == typeof(char))
readExpr = $"ConvertToChar(reader.GetValue(index), {GetValueString(pt, defVal)})";
else
throw new InvalidOperationException($"不支援屬性型別 {p.Name} {pt.FullName}");
writer.WriteLine($"record.{p.Name} = {readExpr};");
writer.EndGroup("}");
}
writer.WriteLine("");
writer.WriteLine("return record;");
writer.EndGroup("}// InnerReadRecord");
XmlTextWriter/StringWriter 等程式碼產生輔助類別 (writer.BeginGroup/EndGroup 自動縮排)。if (index >= 0) 區塊,呼叫對應 ConvertToXxx 靜態方法處理 DBNull、型別轉換、格式化。DateTime 特殊處理:支援 ReadFormat (如 yyyyMMdd) 並以 DateTime.ParseExact 解析。CSharpCodeProvider 編譯成組件快取,運行期直接呼叫強型別方法,零反射開銷。將反射掃描、型別檢查、程式碼生成前置於啟動/首次使用階段,運行期熱路徑為直接方法呼叫,大幅提升大量資料讀取效能。