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;
}

 

posted @ 2015-06-13 11:05  `Laimic  阅读(203)  评论(0)    收藏  举报