/// <summary> /// 输出对象_输出. /// </summary> /// <param name="iw">带缩进输出者.</param> /// <param name="obj">object.</param> /// <param name="context">Context.</param> /// <param name="tp">类型.</param> /// <param name="showBaseName">是否显示基类类型的名称.</param> /// <returns>检查是否支持此对象的输出, 支持的话返回true, 否则返回false.</returns> public virtual bool WriterObject_Write(IIndentedWriter iw, object obj, IndentedWriterContext context, Type tp, bool showBaseName) { // write. if ((m_Options & IndentedObjectFunctorOptions.NotWrite) != 0) { return(true); } if (!iw.Indent(obj)) { return(false); } //if (null != context) { // foreach (KeyValuePair<Type, object> p in context.TypeOwners) { // iw.Write(p.Key.FullName); // iw.Write('/'); // } // iw.WriteLine(); //} bool needtitle = true; bool showmember = true; // 显示成员. if (0 == (m_Options & IndentedObjectFunctorOptions.ArrayMember) && tp.IsArray) { showmember = false; } if (showmember) { WriterObject_WriteMember(iw, obj, context, tp, showBaseName, ref needtitle); } else { WriterObject_WriteTitle(iw, obj, context, tp, showBaseName); } WriterObject_WriteEnumerate(iw, obj, context, tp); iw.Unindent(); return(!needtitle); }
/// <summary> /// 通知枚举成员结束. /// </summary> /// <param name="iw">带缩进输出者.</param> /// <param name="owner">欲查询成员的对象.</param> /// <param name="tp">类型.</param> /// <param name="options">成员选项. </param> /// <param name="handle">每个成员的处理过程. </param> /// <param name="context">环境对象. </param> /// <returns>若在开始枚举成员之前, 返回值表示是否允许枚举. 其他时候忽略.</returns> public bool NotifyForEachMemberEnd(IIndentedWriter iw, object owner, Type tp, IndentedWriterMemberOptions options, EventHandler <IndentedWriterMemberEventArgs> handle, IndentedWriterContext context) { bool rt = true; IndentedWriterForEachMemberNotify p = ForEachMemberEnd; if (null != p) { rt = p(iw, owner, tp, options, handle, context); } if (m_TypeOwners.Count > 0) { m_TypeOwners.RemoveAt(m_TypeOwners.Count - 1); } return(rt); }
/// <summary> /// 通知开始枚举成员. /// </summary> /// <param name="iw">带缩进输出者.</param> /// <param name="owner">欲查询成员的对象.</param> /// <param name="tp">类型.</param> /// <param name="options">成员选项. </param> /// <param name="handle">每个成员的处理过程. </param> /// <param name="context">环境对象. </param> /// <returns>若在开始枚举成员之前, 返回值表示是否允许枚举. 其他时候忽略.</returns> public bool NotifyForEachMemberBegin(IIndentedWriter iw, object owner, Type tp, IndentedWriterMemberOptions options, EventHandler <IndentedWriterMemberEventArgs> handle, IndentedWriterContext context) { bool rt = true; // check. if (null != owner && m_VisitOnce) { // 检查访问. if (m_VisitList.IndexOf(owner) >= 0) { return(false); } m_VisitList.Add(owner); } if (null != tp && !tp.IsArray) { // 连续相同类型对象的最大数量. if (m_SameTypeGroupMax > 0 && null != owner) { int cnt = 0; for (int i = m_TypeOwners.Count - 1; i >= 0; --i) { KeyValuePair <Type, object> pr = m_TypeOwners[i]; if (null == pr.Value) { break; } if (tp.Equals(pr.Key)) { ++cnt; if (cnt >= m_SameTypeGroupMax) { return(false); } } else { break; } } } // 相同类型的最大数量. if (m_SameTypeMax > 0) { int cnt = 0; foreach (KeyValuePair <Type, object> pr in m_TypeOwners) { if (tp.Equals(pr.Key)) { ++cnt; if (cnt >= m_SameTypeMax) { return(false); } } } } } // notify. m_TypeOwners.Add(new KeyValuePair <Type, object>(tp, owner)); IndentedWriterForEachMemberNotify p = ForEachMemberBegin; if (null != p) { rt = p(iw, owner, tp, options, handle, context); } 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); }
/// <summary> /// 输出类型的静态成员, 会输出字段,属性与方法. /// </summary> /// <param name="iw">带缩进输出者.</param> /// <param name="tp">type.</param> /// <param name="context">State Object. Can be null.</param> /// <returns>返回是否成功输出.</returns> public static bool WriteTypeStaticM(IIndentedWriter iw, Type tp, IndentedWriterContext context) { return(WriteTypeStatic(iw, tp, context, IndentedWriterMemberOptions.OnlyStatic | IndentedWriterMemberOptions.AllowMethod)); }
/// <summary> /// 输出类型的静态成员, 拥有选项参数. /// </summary> /// <param name="iw">带缩进输出者.</param> /// <param name="tp">type.</param> /// <param name="context">State Object. Can be null.</param> /// <param name="options">选项. 必须有 <see cref="IndentedWriterMemberOptions.OnlyStatic"/> 标志.</param> /// <returns>返回是否成功输出.</returns> /// <remarks> /// 当 <paramref name="options"/> 具有 <see cref="IndentedWriterMemberOptions.AllowMethod"/> 标志时,还会显示方法信息. 方法必须有返回值, 且没有泛型参数, 其他情况有: /// <para>参数数量为0个;</para> /// <para>参数数量为1个, 且参数类型为枚举或bool.</para> /// </remarks> public static bool WriteTypeStatic(IIndentedWriter iw, Type tp, IndentedWriterContext context, IndentedWriterMemberOptions options) { if (null == iw) { return(false); } if (null == tp) { return(false); } if (0 == (options & IndentedWriterMemberOptions.OnlyStatic)) { return(false); } if (!iw.Indent(tp)) { return(false); } iw.WriteLine(string.Format("# <{0}>", tp.FullName)); //IndentedWriterUtil.ForEachMember(iw, null, tp, options, null, context); IndentedWriterUtil.ForEachMember(iw, null, tp, options, delegate(object sender, IndentedWriterMemberEventArgs e) { MethodInfo memberinfo = e.MemberInfo as MethodInfo; if (null != memberinfo) { //string name = memberinfo.Name; if (memberinfo.IsStatic && !memberinfo.IsSpecialName && null != memberinfo.ReturnType && !memberinfo.ReturnType.Equals(typeof(void))) { ParameterInfo[] pis = memberinfo.GetParameters(); if (false) { } else if (0 == pis.Length) { try { e.Value = memberinfo.Invoke(null, null); if (null == e.WriteProc) { e.WriteProc = IndentedObjectFunctor.CommonProc; } if (null == e.Value && null == e.AppendComment) { e.AppendComment = string.Format("<{0}>", memberinfo.ReturnType.Name); } e.HasDefault = true; } catch { // 忽略. } } else if (WriteSimpleMethod(iw, memberinfo, null, null, IndentedWriterValueOptions.Default, e.AppendComment)) { e.IsCancel = true; } } } }, context); iw.Unindent(); return(true); }
/// <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="obj">object.</param> /// <param name="context">Context.</param> /// <param name="tp">类型.</param> public virtual void WriterObject_WriteEnumerate(IIndentedWriter iw, object obj, IndentedWriterContext context, Type tp) { if (0 != (m_Options & IndentedObjectFunctorOptions.NoEnumerate)) { return; } IEnumerable lst = obj as IEnumerable; if (null == lst) { return; } int i = 0; foreach (object p in lst) { string name = string.Format("[{0}]", i); IndentedWriterObjectProc proc = null; if (null != context) { proc = IndentedWriterUtil.LookupWriteProcAt(p, context, context.Procs); } if (null == proc && (m_WriterOptions & IndentedWriterMemberOptions.NoCommonProcs) == 0) { if (IndentedObjectFunctor.CommonProc(null, p, context)) { proc = IndentedObjectFunctor.CommonProc; } } IndentedWriterUtil.WriteLineValue(iw, name, p, IndentedWriterValueOptions.Default, null); if (null != proc) { proc(iw, p, context); } // next. ++i; } }
/// <summary> /// 输出对象_检查对象. /// </summary> /// <param name="iw">带缩进输出者.</param> /// <param name="obj">object.</param> /// <param name="context">Context.</param> /// <param name="tp">返回 类型.</param> /// <param name="showBaseName">返回 是否显示基类类型的名称.</param> /// <returns>检查是否支持此对象的输出, 支持的话返回true, 否则返回false.</returns> public virtual bool WriterObject_CheckObject(IIndentedWriter iw, object obj, IndentedWriterContext context, out Type tp, out bool showBaseName) { // check. tp = null; showBaseName = false; // 是否显示基类类型的名称. if (null == obj) { return(false); } tp = obj.GetType(); if (null == m_BaseType) { return(false); } #if NETFX_CORE TypeInfo ti = tp.GetTypeInfo(); if (ti.IsEnum) { return(false); } if (ti.IsPointer) { return(false); } if (ti.IsPrimitive) { return(false); } #else if (tp.IsEnum) { return(false); } if (tp.IsPointer) { return(false); } if (tp.IsPrimitive) { return(false); } #endif if ((m_Options & IndentedObjectFunctorOptions.OnlyType) != 0) { if (!m_BaseType.Equals(tp)) { return(false); } } else { #if NETFX_CORE if (!m_BaseType.GetTypeInfo().IsAssignableFrom(ti)) { return(false); } #else if (!m_BaseType.IsInstanceOfType(obj)) { return(false); } #endif if ((m_Options & IndentedObjectFunctorOptions.OnlyMember) != 0) { tp = m_BaseType; } else { showBaseName = !m_BaseType.Equals(tp) && !m_BaseType.Equals(typeof(object)); } } if ((m_Options & IndentedObjectFunctorOptions.AllowSimple) == 0) { if (IndentedWriterUtil.IsSimpleType(tp)) { return(false); } } return(true); }