C# - Reflection
类的反射
Type t = obj.GetType();
// typeof() 的参数必须要是类型, 而不能是变量 或者是类型变量. Type t = typeof(Int);
// 用于加载不是本地的 .dll 中的类 Assembly.load("程序集").GetType("程序集下的类名")
// 用于获取当前程序集下的类
// 获取已加载到此应用程序域的执行上下文中的程序集
// 这个方法只能获取已经加载到此应用程序域的程序集。.Net 有延迟加载机制,有的时候我们可能不能及时的获取到需要的程序集(比如在启动的时候)
Assembly.GetExecutingAssembly().GetType("类名")
// 返回所有页编译都必须引用的程序集引用的列表
System.Web.Compilation.BuildManager.GetReferencedAssemblies()
// 泛型类的获取 Type genericType = typeof(GenericType<>); Type[] templateTypeSet = new[] { typeof(string), typeof(int) }; Type implementType = genericType.MakeGenericType(templateTypeSet);
属性的反射
// 获取某对象的类型 Type type = obj.GetType(); // 获取某类型某个属性的信息 PropertyInfo proInfo = type.GetProperty("Id"); // 获取该字段的类型 var propertyType = proInfo.PropertyType; // 获取该属性的值 var value = proInfo.GetValue(obj); Console.WriteLine(value);
创建实例
object obj = Assembly.GetExecutingAssembly().CreateInstance("类的完全限定名(即包括命名空间)"); object obj = Assembly.LoadFile("程序集路径").CreateInstance("类的完全限定名(即包括命名空间)"); object obj = type.Assembly.CreateInstance("类的完全限定名"); object obj = Activator.CreateInstance(type, true)
获取属性的特性
Type t = obj.GetType(); foreach(var p in t.GetProperties()){ object[] attrs = p.GetCustomAttributes(true); foreach(var attr in attrs){ Type t2 = attr.GetType(); } }
调用反射方法
Type type = obj.GetType();
MethodInfo me = type.GetMethod("function", BindingFlags.NonPublic | BindingFlags.Instance); // 如果方法是重载方法的话, 需要指定其参数的Type
// 其中, Type 数组的元素数量对应重载函数的参数数量
MethodInfo me = type.GetMethod("function", new Type[] {});
// object 为参数组 me.Invoke(this, new object[] {});
// 注:
// 反射方法的执行可能无法被捕获错误
// 例如:
public void Func()
{
throw new Exception("Exception");
}
public void Main()
{
try {
MethodInfo me = this.GetType().GetMethod("Func");
me.Invoke(this, null);
}
catch(Exception ex) {
Console.WriteLine(ex.Message);
}
}
或者
dynamic dy = obj; dy.function();
类型转换
/// <summary> /// 将一个对象转换为指定类型 /// </summary> /// <param name="obj">待转换的对象</param> /// <param name="type">目标类型</param> /// <returns>转换后的对象</returns> public static object ConvertToObject(object obj, Type type) { if (type == null) return obj; if (obj == null) return type.IsValueType ? Activator.CreateInstance(type) : null; Type underlyingType = Nullable.GetUnderlyingType(type); if (type.IsAssignableFrom(obj.GetType())) // 如果待转换对象的类型与目标类型兼容,则无需转换 { return obj; } else if ((underlyingType ?? type).IsEnum) // 如果待转换的对象的基类型为枚举 { if (underlyingType != null && string.IsNullOrEmpty(obj.ToString())) // 如果目标类型为可空枚举,并且待转换对象为null 则直接返回null值 { return null; } else { return Enum.Parse(underlyingType ?? type, obj.ToString()); } } else if (typeof(IConvertible).IsAssignableFrom(underlyingType ?? type)) // 如果目标类型的基类型实现了IConvertible,则直接转换 { try { return Convert.ChangeType(obj, underlyingType ?? type, null); } catch { return underlyingType == null ? Activator.CreateInstance(type) : null; } } else { TypeConverter converter = TypeDescriptor.GetConverter(type); if (converter.CanConvertFrom(obj.GetType())) { return converter.ConvertFrom(obj); } ConstructorInfo constructor = type.GetConstructor(Type.EmptyTypes); if (constructor != null) { object o = constructor.Invoke(null); PropertyInfo[] propertys = type.GetProperties(); Type oldType = obj.GetType(); foreach (PropertyInfo property in propertys) { PropertyInfo p = oldType.GetProperty(property.Name); if (property.CanWrite && p != null && p.CanRead) { property.SetValue(o, ConvertToObject(p.GetValue(obj, null), property.PropertyType), null); } } return o; } } return obj; }