using System; using System.ComponentModel; using System.Drawing; using System.IO; using System.Reflection; using System.Resources; using System.Text; namespace Masuit.Tools.Reflection { /// /// 反射辅助类 /// public static class ReflectHelper { #region 成员读写 /// /// 获取实体相关属性的值 /// /// 反射对象 /// 属性名 /// 属性值 public static object GetInstanceValue(this object obj, string propertyName) { object objRet = null; if (!string.IsNullOrEmpty(propertyName)) { PropertyDescriptor descriptor = TypeDescriptor.GetProperties(obj).Find(propertyName, true); if (descriptor != null) { objRet = descriptor.GetValue(obj); } } return objRet; } #endregion #region 方法调用 /// /// 直接调用内部对象的方法/函数或获取属性(支持重载调用) /// /// 泛型T /// 目标数据类型 /// 函数名称,区分大小写。 /// 如果调用属性,则为相关对象的初始化数据,否则为Null。 /// 函数参数信息 /// 运行结果 /// 非法异常 public static T InvokeMethodOrGetProperty(this Type refType, string funName, object[] objInitial, params object[] funParams) { MemberInfo[] mis = refType.GetMember(funName); if (mis.Length < 1) { throw new InvalidProgramException(string.Concat("函数/方法 [", funName, "] 在指定类型(", refType.ToString(), ")中不存在!")); } MethodInfo targetMethod = null; StringBuilder pb = new StringBuilder(); foreach (MemberInfo mi in mis) { if (mi.MemberType != MemberTypes.Method) { if (mi.MemberType == MemberTypes.Property) { #region 调用属性方法Get targetMethod = ((PropertyInfo)mi).GetGetMethod(); break; #endregion } throw new InvalidProgramException(string.Concat("[", funName, "] 不是有效的函数/属性方法!")); } #region 检查函数参数和数据类型 绑定正确的函数到目标调用 MethodInfo curMethod = (MethodInfo)mi; ParameterInfo[] pis = curMethod.GetParameters(); if (pis.Length == funParams.Length) { var validParamsLen = true; pb = new StringBuilder(); bool paramFlag = true; int paramIdx = 0; #region 检查数据类型 设置validParamsType是否有效 foreach (ParameterInfo pi in pis) { pb.AppendFormat("Parameter {0}: Type={1}, Name={2}\n", paramIdx, pi.ParameterType, pi.Name); //不对Null和接受Object类型的参数检查 if (funParams[paramIdx] != null && pi.ParameterType != typeof(object) && (pi.ParameterType != funParams[paramIdx].GetType())) { #region 检查类型是否兼容 try { funParams[paramIdx] = Convert.ChangeType(funParams[paramIdx], pi.ParameterType); } catch (Exception) { paramFlag = false; } #endregion //break; } ++paramIdx; } #endregion bool validParamsType; if (paramFlag) { validParamsType = true; } else { continue; } if (validParamsLen && validParamsType) { targetMethod = curMethod; break; } } #endregion } if (targetMethod != null) { object objReturn; #region 兼顾效率和兼容重载函数调用 try { object objInstance = Activator.CreateInstance(refType, objInitial); objReturn = targetMethod.Invoke(objInstance, BindingFlags.InvokeMethod, Type.DefaultBinder, funParams, System.Globalization.CultureInfo.InvariantCulture); } catch (Exception) { objReturn = refType.InvokeMember(funName, BindingFlags.InvokeMethod, Type.DefaultBinder, null, funParams); } #endregion return (T)objReturn; } throw new InvalidProgramException(string.Concat("函数/方法 [", refType.ToString(), ".", funName, "(args ...) ] 参数长度和数据类型不正确!\n 引用参数信息参考:\n", pb.ToString())); } /// /// 调用相关实体类型的函数方法 /// /// 泛型T /// 实体类型 /// 函数名称 /// 函数参数列表 /// 调用该函数之后的结果 public static T InvokeFunction(this Type refType, string funName, params object[] funParams) { return InvokeMethodOrGetProperty(refType, funName, null, funParams); } #endregion #region 资源获取 /// /// 获取程序集资源的位图资源 /// /// 程序集中的某一对象类型 /// 资源的根名称。例如,名为“MyResource.en-US.resources”的资源文件的根名称为“MyResource”。 /// 资源项名称 public static Bitmap LoadBitmap(this Type assemblyType, string resourceHolder, string imageName) { Assembly thisAssembly = Assembly.GetAssembly(assemblyType); var rm = new ResourceManager(resourceHolder, thisAssembly); return (Bitmap)rm.GetObject(imageName); } /// /// 获取程序集资源的文本资源 /// /// 程序集中的某一对象类型 /// 资源项名称 /// 资源的根名称。例如,名为“MyResource.en-US.resources”的资源文件的根名称为“MyResource”。 public static string GetStringRes(this Type assemblyType, string resName, string resourceHolder) { Assembly thisAssembly = Assembly.GetAssembly(assemblyType); ResourceManager rm = new ResourceManager(resourceHolder, thisAssembly); return rm.GetString(resName); } /// /// 获取程序集嵌入资源的文本形式 /// /// 程序集中的某一对象类型 /// 字符集编码 /// 嵌入资源相对路径 /// 如没找到该资源则返回空字符 public static string GetManifestString(this Type assemblyType, string charset, string resName) { Assembly asm = Assembly.GetAssembly(assemblyType); Stream st = asm.GetManifestResourceStream(string.Concat(assemblyType.Namespace, ".", resName.Replace("/", "."))); if (st == null) { return ""; } int iLen = (int)st.Length; byte[] bytes = new byte[iLen]; st.Read(bytes, 0, iLen); return (bytes != null) ? Encoding.GetEncoding(charset).GetString(bytes) : ""; } #endregion } }