/// <summary> /// 初始化需要扫描的字段集合 /// </summary> /// <param name="scanner">对象扫描</param> internal void CreateScanFiled(ReflectionTypeScanner scanner) { BaseType = (ReflectionObjectType)scanner.GetObjectType(Type.BaseType); List <KeyValue <FieldInfo, ReflectionType> > fieldList = null; foreach (FieldInfo field in Type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly)) { Type fieldType = field.FieldType; if (!fieldType.IsPointer && fieldType != typeof(System.Reflection.Pointer)) { ReflectionType objectType = scanner.GetObjectType(fieldType); if (objectType.IsScan != 0 || IsScanDerived(fieldType)) { if (fieldList == null) { fieldList = new List <KeyValue <FieldInfo, ReflectionType> >(); } fieldList.Add(new KeyValue <FieldInfo, ReflectionType>(field, objectType)); } } } if (fieldList != null) { ScanFields = fieldList.ToArray(); } else if (BaseType.IsScan == 0) { IsScan = 0; } }
/// <summary> /// 获取对象类型 /// </summary> /// <param name="type"></param> /// <returns>对象类型</returns> internal ReflectionType GetObjectType(Type type) { if (type.IsPrimitive || type.IsEnum || type.IsPointer) { return(ReflectionObjectType.NullType); } if (type.IsInterface) { return(ReflectionObjectType.InterfaceType); } if (type.IsClass || type.IsValueType) { ReflectionType objectType; if (!ObjectTypeCache.TryGetValue(type, out objectType)) { if (type.IsArray) { ReflectionArrayType reflectionType = new ReflectionArrayType(type); ObjectTypeCache.Add(type, objectType = reflectionType); reflectionType.GetElementType(this); } else { ReflectionObjectType reflectionType = new ReflectionObjectType(type); ObjectTypeCache.Add(type, objectType = reflectionType); reflectionType.CreateScanFiled(this); } } return(objectType); } return(ReflectionObjectType.NullType); }
/// <summary> /// 反射模式对象扫描 /// </summary> /// <param name="value">扫描的对象</param> /// <param name="objectType">对象类型</param> /// <param name="isArray">对象是否数组元素,数组元素不统计根静态字段</param> internal ReflectionObjectScanner(object value, ReflectionObjectType objectType, bool isArray) { this.value = value; this.objectType = objectType; this.isArray = isArray; index = 0; }
/// <summary> /// 读取下一个数据 /// </summary> /// <param name="scanner"></param> internal void Next(ref ReflectionScanner scanner) { object value = this.value; bool isArray = this.isArray; int isEndIndex = 0; do { KeyValue <FieldInfo, ReflectionType> field = this.objectType.ScanFields[index++]; if (index == this.objectType.ScanFields.Length) { --scanner.Objects.Length; if (this.objectType.BaseType.IsScan != 0) { this.objectType.BaseType.Append(ref scanner, value, isArray); } isEndIndex = 1; } object fieldValue = field.Key.GetValue(value); if (fieldValue != null) { ReflectionType objectType = field.Value; Type fieldType = fieldValue.GetType(); if (fieldType != objectType.Type) { objectType = scanner.Scanner.GetObjectType(fieldType); } if (objectType.IsScan != 0) { if (fieldType.IsClass) { if (scanner.AddObject(fieldValue)) { if (!isArray) { objectType.Add(scanner.FieldInfo, scanner.Scanner); } if (objectType.Append(ref scanner, fieldValue, false) == 0) { return; } } else if (scanner.IsLimitExceeded) { return; } } else if (objectType.Append(ref scanner, fieldValue, false) == 0) { return; } } } }while (isEndIndex == 0); }
/// <summary> /// 对象类型 /// </summary> /// <param name="type">类型</param> internal ReflectionObjectType(Type type) : base(type) { IsScan = 1; ScanFields = EmptyArray <KeyValue <FieldInfo, ReflectionType> > .Array; BaseType = NullType; }
/// <summary> /// 接口类型 /// </summary> /// <param name="baseType"></param> private ReflectionObjectType(ReflectionObjectType baseType) : base(typeof(object)) { BaseType = baseType; ScanFields = EmptyArray <KeyValue <FieldInfo, ReflectionType> > .Array; IsScan = 1; }
/// <summary> /// 空对象类型 /// </summary> private ReflectionObjectType() : base(typeof(object)) { BaseType = this; ScanFields = EmptyArray <KeyValue <FieldInfo, ReflectionType> > .Array; }
static ReflectionObjectType() { InterfaceType = new ReflectionObjectType(NullType = new ReflectionObjectType()); }