c# 反射

从程序集到方法和属性的调用

原文地址:https://www.cnblogs.com/siyi/p/5009032.html

//动态加载程序集
Assembly ass = Assembly.LoadFile(@"F:\Cheng_20140819\VS2012_WorkSpace\Assembly\Assembly\TestClassLibary\bin\Debug\TestClassLibary.dll");


//利用GetTypes获取所有类型 public  internal  都能拿到
Type[] ts = ass.GetTypes();
foreach (Type item in ts)
{
     
	Console.WriteLine(item.Name);
}


//只获取公开的类型
//获取导出的类型
Type[] publicTypes = ass.GetExportedTypes();
foreach (Type item in publicTypes)
{
     
	Console.WriteLine("--->>"+item.Name);
}



//获取特定的Type,类型需要完全限定名称 : 记得带上命名空间哟~
Type personType = ass.GetType("TestClassLibary.Person");




//根据特定的Type 来创建对象,无参数构造函数
object personObj = Activator.CreateInstance(personType);

//获取特定的方法
MethodInfo method = personType.GetMethod("Add");

//调用,参数1 代表获取的类型的对象 ,参数2  代表调用的方法的参数列表
object obj= method.Invoke(personObj, new object[] {
      2, 3 });


//获取参数的类型
ParameterInfo[] args = methodInfo.GetParameters();
Args[0].ParameterType



//获取继承接口的类型
Type[] types = type.GetInterfaces()


//方法设置泛型
methodInfo.MakeGenericMethod(type);

//--------------------------------调用属性---------------------
Assembly ass = Assembly.LoadFile (@"F:\Cheng_20140819\VS2012_WorkSpace\Assembly\Assembly\TestClassLibary\bin\Debug\TestClassLibary.dll");

Type t = ass.GetType ("TestClassLibary.Person");

object obj = Activator.CreateInstance (t);

PropertyInfo pifo = t.GetProperty ("Name");

pifo.SetValue (obj, "cheng");

MethodInfo mifo = t.GetMethod ("WriteName");

mifo.Invoke (obj, null);

//--------------------------------利用特定的构造函数
Assembly ass = Assembly.LoadFile (@"F:\Cheng_20140819\VS2012_WorkSpace\20151129_Heima_Day11_Assembly\Assembly\TestClassLibary\bin\Debug\TestClassLibary.dll");

Type personType = ass.GetType ("TestClassLibary.Person");

//这里使用 ctor    GetConstructor()  其参数列表就 是指定的构造函数的列表 
ConstructorInfo ctor = personType.GetConstructor (new Type[] {
      typeof (string), typeof (int), typeof (string) });

object o = ctor.Invoke (new object[] {
      "ccc", 20, "CCC@sina.cn" });

Console.WriteLine (o.ToString ());
MethodInfo mInfo = personType.GetMethod ("WriteName");

mInfo.Invoke (o, null);

反射实例带参数的特性类

特性

public abstract class BaseValidationAttribute: Attribute
    {
     
        public BaseValidationAttribute(string errorMessage) {
     
            ErrorMessage = errorMessage;
        }

        public string ErrorMessage {
      get; set; }

        public abstract bool IsValid();
}



public class RoleAuthAttribute : BaseValidationAttribute
    {
     
        private List<string> _Role = new List<string>();

        public RoleAuthAttribute(object[] role) : base("授权错误") {
     
            foreach (var item in role) {
     
                _Role.Add(item.ToString());
            }
        }

        public RoleAuthAttribute(object[] role, string error) : base(error) {
     
            foreach (var item in role)
            {
     
                _Role.Add(item.ToString());
            }
        }

        public override bool IsValid()
        {
     
            IPrincipal principal = GenerateAndGetPrincipal.GetPrincipal();
            if (principal == null)
            {
     
                return false;
            }
            foreach (var item in _Role) {
     
                if (principal.IsInRole(item) == true)
                    return true;
            }

            return false;
        }
 }

验证

public static bool Validate(Type type,out string errorMessage)
        {
     
            errorMessage = null;

            foreach (var item in type.CustomAttributes)
            {
     
  				//获取构造函数信息
                ConstructorInfo service = item.Constructor;
                if (service.DeclaringType.IsSubclassOf(typeof(BaseValidationAttribute)))
                {
     
                    List<object> paramList = new List<object>();
					//获取构造函数实参信息
                    foreach(var parameterInfoItem in item.ConstructorArguments) {
     
                        List<object> list = new List<object>();
                        foreach (var parameterItem in (ReadOnlyCollection<CustomAttributeTypedArgument>) parameterInfoItem.Value) {
     
							//添加实参值
                            list.Add(parameterItem.Value);
                        }
                        paramList.Add(list.ToArray());
                    }
  					//调用构造方法生成特性实例
                    BaseValidationAttribute validationAttribute = service.Invoke(paramList.ToArray()) as BaseValidationAttribute;
				 	//调用特性的方法进行验证
                    bool isSuccess = validationAttribute.IsValid();
                    if (isSuccess == false)
                    {
     
                        errorMessage = validationAttribute.ErrorMessage;
                        return false;
                    }
                }
            }

            return true;
}

反射搜索标记 BindingFlags

例:查找当前类的方法公共方法,不包括父类

var type = typeof(ClassA);
var methods = type.GetMembers(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.DeclaredOnly);

BindingFlags.Instance和BindingFlags.Static二者必须有一项或者都有

BindingFlags枚举值:
BindingFlags.IgnoreCase:表示忽略 name 的大小写,不应考虑成员名的大小写
BindingFlags.DeclaredOnly:只应考虑在所提供类型的层次结构级别上声明的成员。不考虑继承成员。
BindingFlags.Instance:只搜索实例成员
BindingFlags.Static:只搜索静态成员
BindingFlags.Public:只搜索公共成员
BindingFlags.NonPublic:只搜索非公共成员
BindingFlags.FlattenHierarchy:应返回层次结构上的公共静态成员和受保护的静态成员。不返回继承类中的私有静态成员。静态成员包括字段、方法、事件和属性。不返回嵌套类型。
BindingFlags.InvokeMethod:表示调用方法,而不调用构造函数或类型初始值设定项。对 SetField 或 SetProperty 无效。
BindingFlags.CreateInstance:表示调用构造函数。忽略 name。对其他调用标志无效。
BindingFlags.GetField:表示获取字段值。
BindingFlags.SetField:表示设置字段值。
BindingFlags.GetProperty:表示获取属性。
BindingFlags.SetProperty:表示设置属性。

你可能感兴趣的