在記錄日誌的時候,有時候需要知道一個實體的每個欄位的值,這時候需要用反射來遍曆成員,拼成字串返回,如果成員仍然是一個自訂類型,需要遞迴執行。
實現方式:
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Reflection;using System.Collections;namespace ServerToolServer.Util{ public class ObjectDumper { /// <summary> /// 本次記錄最大的位元組數 /// </summary> private static int MAXLENGTH = 16384; /// <summary> /// 當前要記錄的對象 /// </summary> private static object lastObj = null; /// <summary> /// 反射出obj的欄位名和欄位值 /// </summary> /// <typeparam name="T">要反射的類型</typeparam> /// <param name="obj">實體</param> /// <returns>欄位名:欄位值</returns> public static string GetObjStr(object obj) { if (obj == null) { return ""; } StringBuilder ret = new StringBuilder(30); FieldInfo[] fields = obj.GetType().GetFields(); if (fields == null || fields.Length == 0) { return ret.ToString(); } else { foreach (FieldInfo eachField in fields) { GetObjStr(obj, eachField, ret); } } return ret.ToString(); } /// <summary> /// 反射出對象的欄位名:值 /// </summary> /// <param name="entity">要反射的對象</param> /// <param name="obj">欄位</param> /// <param name="str">記錄的stringbuilder</param> public static void GetObjStr(object entity, object obj, StringBuilder str) { try { ////避免無限遞迴,確保一個對象只會被記錄一次 if (Object.ReferenceEquals(obj, lastObj)) { return; } lastObj = obj; if (entity == null || obj == null) { return; } if (str.Length > MAXLENGTH) { str.Append("...to long..."); return; } FieldInfo f = obj as FieldInfo; string typeName = f == null ? obj.GetType().Name : f.Name; Type type = f == null ? obj.GetType() : f.FieldType; object value = f == null ? obj : f.GetValue(entity); if (type.IsValueType || type == typeof(string)) { if (str.Length > MAXLENGTH) { str.Append("...to long..."); return; } str.Append(typeName); str.Append(" : "); str.Append(value); str.Append("\r\n"); return; } ////如果成員是個集合,遞迴遍曆 if (typeof(IEnumerable).IsAssignableFrom(type)) { IEnumerable ie = value as IEnumerable; if (ie != null) { IEnumerator list = ie.GetEnumerator(); while (list.MoveNext()) { ////基礎資料型別 (Elementary Data Type)或者string if (list.Current.GetType().IsValueType || list.Current.GetType() == typeof(string)) { if (str.Length > MAXLENGTH) { str.Append("...to long..."); return; } else { str.Append(type); str.Append(" : "); str.Append(list.Current); str.Append("\r\n"); } } ////自訂類型 else { str.Append(list.Current.GetType()); str.Append("."); FieldInfo[] fields = list.Current.GetType().GetFields(); foreach (FieldInfo subField in fields) { if (str.Length > MAXLENGTH) { str.Append("...to long..."); return; } GetObjStr(list.Current, subField, str); } } } } } else { str.Append(type); str.Append("."); FieldInfo[] fields = type.GetFields(); if (fields.Length == 0) { return; } foreach (FieldInfo subField in fields) { if (str.Length > MAXLENGTH) { str.Append("...to long..."); return; } GetObjStr(value, subField, str); } } } catch (Exception ex) { return; } } }}
以上就是c# 反射 遍曆實體的所有欄位,ObjectDumper類實現的詳細介紹的內容,更多相關內容請關注topic.alibabacloud.com(www.php.cn)!