/// <summary> /// 输出对象的各个成员. /// </summary> /// <param name="iw">带缩进输出者.</param> /// <param name="owner">欲查询成员的对象. 查询静态成员时可以设为 null.</param> /// <param name="tp">类型. 当 <paramref name="owner"/> 非 null 时, 可设为null, 即自动设为 <c>owner.GetType()</c> . </param> /// <param name="options">成员选项. 实际的成员选项是本参数与 <see cref="IndentedWriterContext.MemberOptions"/> 属性做或运算后的值. </param> /// <param name="handle">每个成员的处理过程, 可以为 null. 默认在调用时会将其 <c>sender</c>参数设为null. </param> /// <param name="context">环境对象, 可以为 null. 会嵌套传递. </param> /// <returns>是否成功.</returns> public static bool ForEachMember(IIndentedWriter iw, object owner, Type tp, IndentedWriterMemberOptions options, EventHandler <IndentedWriterMemberEventArgs> handle, IndentedWriterContext context) { bool rt = false; if (null == tp) { if (null == owner) { return(rt); } tp = owner.GetType(); } if (null == owner && (options & IndentedWriterMemberOptions.OnlyStatic) == 0) { throw new ArgumentException("options not has Static, but owner is null.", "bindingAttr"); } // notify begin. if (null == context) { context = new IndentedWriterContext(); // 自动创建环境. 有可能以后调整设计, 所以后面还是检查 context. } if (null != context) { if (!context.NotifyForEachMemberBegin(iw, owner, tp, options, handle, context)) { return(false); } } // args IndentedWriterMemberEventArgs args = new IndentedWriterMemberEventArgs(); args.IsCancel = false; args.IsCancelAll = false; args.HasDefault = false; args.IndentedWriter = iw; args.Owner = owner; args.OwnerType = tp; args.MemberOptions = options; //args.Procs = procs; args.Context = context; // foreach. IndentedWriterMemberOptions realoptions = options; if (null != context) { realoptions |= context.MemberOptions; } foreach (MemberInfo mi in GetMembers(tp, realoptions)) { string AppendComment2 = null; // 备用的附加注释. 可能会在 args.AppendComment 为null时 使用. args.IsCancel = true; args.HasDefault = false; args.MemberInfo = mi; args.MemberName = TypeUtil.GetMemberNameAuto(mi, DefaultMemberNameOption); //mi.Name; args.Value = null; args.ValueOptions = IndentedWriterValueOptions.ExistValue; args.AppendComment = null; args.WriteProc = null; //Debug.WriteLine(mi.ToString()); // //bool bOk = false; //object value = null; //IndentedWriterObjectProc writeproc = null; //IndentedWriterValueOptions iwvo = IndentedWriterValueOptions.ExistValue; //bool isdefault = false; // get value. if (false) { } else if (mi is FieldInfo) { FieldInfo fi = mi as FieldInfo; args.IsCancel = false; if (true) { try { args.Value = fi.GetValue(owner); args.ValueOptions = IndentedWriterValueOptions.Default; args.HasDefault = true; AppendComment2 = string.Format("<{0}>", fi.FieldType.Name); } catch (Exception ex) { Debug.WriteLine(ex); } } } else if (mi is PropertyInfo) { PropertyInfo pi = mi as PropertyInfo; args.IsCancel = false; if (pi.CanRead && pi.GetIndexParameters().Length <= 0) { try { args.Value = pi.GetValue(owner, null); args.ValueOptions = IndentedWriterValueOptions.Default;; args.HasDefault = true; AppendComment2 = string.Format("<{0}>", pi.PropertyType.Name); } catch (Exception ex) { Debug.WriteLine(ex); } } } else if (mi is MethodInfo) { if ((realoptions & IndentedWriterMemberOptions.AllowMethod) != 0) { MethodInfo methodinfo = mi as MethodInfo; args.IsCancel = false; args.ValueOptions = IndentedWriterValueOptions.AutoHideValue; //args.MemberName = string.Format("{0}()", mi.Name); AppendComment2 = string.Format("<{0}>", methodinfo.ReturnType.Name); } } if (args.IsCancel) { continue; } // get proc. if (null != args.Value) { //args.WriteProc = LookupWriteProcAt(args.Value, context, procs); if (null != context) { args.WriteProc = LookupWriteProcAt(args.Value, context, context.Procs); } //if (null == args.WriteProc && (realoptions & IndentedWriterMemberOptions.NoDefaultProcs) == 0) { // args.WriteProc = LookupWriteProc(args.Value, context); //} if (null == args.WriteProc && (realoptions & IndentedWriterMemberOptions.NoCommonProcs) == 0) { if (IndentedObjectFunctor.CommonProc(null, args.Value, context)) { args.WriteProc = IndentedObjectFunctor.CommonProc; } } } // handle if (null != handle) { //handle(context, mi, value, ref writeproc, ref iwvo, ref isdefault); handle(null, args); } if (args.IsCancelAll) { break; } if (args.IsCancel) { continue; } // show. if (args.HasDefault) { if (null == args.Value && null == args.AppendComment) { args.AppendComment = AppendComment2; } WriteLineValue(iw, args.MemberName, args.Value, args.ValueOptions, args.AppendComment); if (null != args.WriteProc) { args.WriteProc(iw, args.Value, context); } } } // notify begin. if (null != context) { context.NotifyForEachMemberEnd(iw, owner, tp, options, handle, context); } rt = true; return(rt); }
/// <summary> /// 输出派生类及成员. /// </summary> /// <param name="iw">带缩进输出者.</param> /// <param name="basetype">Base Class type.</param> /// <param name="assembly">Assembly.</param> /// <param name="context">State Object. Can be null.</param> /// <returns>返回是否成功输出.</returns> public static bool WriteDerivedClass(IIndentedWriter iw, Type basetype, Assembly assembly, IndentedWriterContext context) { if (null == iw) { return(false); } if (null == basetype) { return(false); } //Type basetype = typeof(Calendar); #if (NETFX_CORE) TypeInfo tiBase = basetype.GetTypeInfo(); #endif //Assembly assembly = basetype.Assembly; if (null == assembly) { #if (NETFX_CORE) assembly = tiBase.Assembly; #else assembly = basetype.Assembly; #endif } if (!iw.Indent(basetype)) { return(false); } iw.WriteLine("# DerivedClass of <{0}>:", basetype.FullName); int cnt = 0; IEnumerable <Type> lst = null; #if (NETFX_CORE) lst = assembly.ExportedTypes; #else lst = assembly.GetExportedTypes(); #endif foreach (Type tp in lst) { // check. #if (NETFX_CORE) TypeInfo ti = tp.GetTypeInfo(); if (!ti.IsAssignableFrom(tiBase)) { continue; } #else if (tp.IsAbstract) { continue; } if (!tp.IsSubclassOf(basetype)) { continue; } #endif // new. object ob = null; try { ob = Activator.CreateInstance(tp); } catch { // 忽略. } if (null == ob) { continue; } // write. iw.WriteLine("DerivedClass[{0}]:\t# <{1}>", cnt, tp.Name); WriteTypeStatic(iw, tp, context); IndentedObjectFunctor.CommonProc(iw, ob, context); ++cnt; } iw.Unindent(); return(true); }