c#反射入门篇(Reflection)——PropertyInfo 发现属性

简介

发现属性 (Property) 的属性 (Attribute) 并提供对属性 (Property) 元数据的访问。

1.如何获取?

Type.GetProperty(String) 获取该类的指定的名字String公开的属性,如果私有会为空
Type.GetProperty(String,BindingFlags) 获取该类的指定的名字String和指定类型BindingFlags的属性
Type.GetProperties() 获取该类的所有公开属性
Type.GetProperties(BindingFlags) 获取该类的所有指定类型BindingFlags的属性

Type.GetMethod(String) 获取该类的指定的名字String公开的函数方法,如果私有会为空
Type.GetMethod(String,BindingFlags) 获取该类的指定的名字String和指定类型BindingFlags的函数方法
Type.GetMethods() 获取该类的所有公开的函数方法
Type.GetMethods(BindingFlags) 获取该类的所有指定类型BindingFlags的函数方法

例子:

先定义个类型

    public class Property
    {
        public int A { get; set; }
        public string B { get; set; }

        private int C { get; set; }
        private string D { get; set; }
    }
PropertyInfo property1 = typeof(Property).GetProperty("A");
PropertyInfo property2 = typeof(Property).GetProperty("C");
Console.WriteLine("公开的" + property1.Name);
Console.WriteLine(property2!=null?"存在":"不存在");

//BindingFlags.Instance(对象) 和 BindingFlags.Static(静态) 必须有一个,
property2 = typeof(Property).GetProperty("C",BindingFlags.Instance|BindingFlags.NonPublic);
Console.WriteLine(property2 != null ? "存在" : "不存在");
PropertyInfo[] propertys1 = typeof(Property).GetProperties();
PropertyInfo[] propertys2 = typeof(Property).GetProperties();
foreach (var item in propertys1)
{
   Console.WriteLine("公开的"+item.Name);
}

propertys2 = typeof(Property).GetProperties(BindingFlags.NonPublic|BindingFlags.Instance);
foreach (var item in propertys2)
{
   Console.WriteLine("私有的的" + item.Name);
}
Console.ReadKey();

结果:
在这里插入图片描述

2.属性

这里就列几个基础的属性,完整属性可以查看c#的API

属性作用
GetMethod获取此属性的 get 访问器 可以看做是一个带返回值的函数
SetMethod获取此属性的 set 访问器 可以看做是带着一个赋值参数T的vold函数
CanRead/CanWrite返回bool用于判断该属性值是否可读/写
PropertyType获取该属性的类型Type
MemberType返回一个枚举表示他是一个属性

3.方法

获取公开的get访问器 就是一个带返回值的函数 如果为空就是私有或者不存在 MethodInfo GetGetMethod();
获取公开和私有的get访问器 就是一个带返回值的函数MethodInfo GetGetMethod(bool nonPublic);
获取公开的set访问器 就是带着一个赋值参数T的vold函数 如果为空就是私有或者不存在 MethodInfo SetGetMethod();
获取公开和私有的set访问器 带着一个赋值参数T的vold函数 MethodInfo GetSetMethod(bool nonPublic);
获取公开的get set访问器 如果为空就是私有或者不存在 MethodInfo[] GetAccessors();
获取公开和私有的get set访问器MethodInfo[] GetAccessors(bool nonPublic);

例子:

先声明个类

public class Property
{
	 public string a;
	
	 public string A1 { 
	     get { Console.WriteLine("运行了一次A1的Get"); return a; } 
	     set { Console.WriteLine("运行了一次A1的Get"); a = value; }
	 }
	 public string A2 { 
	     private get { Console.WriteLine("运行了一次A2的私有的Get"); return a; }  
	     set { Console.WriteLine("运行了一次A2的Set"); a = value; }
	 }
}
Property Instance = Activator.CreateInstance(typeof(Property)) as Property;
Instance.a = "凉_开果";

Console.WriteLine(typeof(Property).GetProperty("A2").GetGetMethod()!=null?"存在":"不存在");
Console.WriteLine("用了GetGetMethod(true)之后");
typeof(Property).GetProperty("A2").GetGetMethod(true).Invoke(Instance, null);

Console.WriteLine("A1公开的get 和 set 访问器{0}个", typeof(Property).GetProperty("A1").GetAccessors().Length);
Console.WriteLine("A2公开的get 和 set 访问器{0}个", typeof(Property).GetProperty("A2").GetAccessors().Length);
Console.WriteLine("A2私有和公开的get 和 set 访问器{0}个", typeof(Property).GetProperty("A2").GetAccessors(true).Length);

Console.WriteLine("未调用Set之前a是:{0}", Instance.a);
typeof(Property).GetProperty("A1").GetSetMethod(true).Invoke(Instance, new object[] { "赋值后的开果"});
Console.WriteLine("调用Set后a是:{0}", Instance.a);

Console.ReadKey();

结果:

总结:

里面的MethodInfo.Invoke不知道什么意思的话 可以看这里MethodInfo
Set那里的Invoke 等于运行了一个带参数函数赋值给a的 之后a就被赋值了

获取 object GetValue(Object包含这个属性类的实例化对象);
赋值SetValue(object包含这个属性类的实例化对象 , object 要赋的值);
当在派生类中被重写时,为直接或间接的基类上的方法返回MethodInfo 就是找到他的 谁创建的这个函数

例子:

先声明个类:

public class Property
{
   public string A { get; set; }
}
 Property Instance = new Property();
 Instance.A = "凉_开果";

 Console.WriteLine(typeof(Property).GetProperty("A").GetValue(Instance));
 Console.WriteLine("修改后");
 typeof(Property).GetProperty("A").SetValue(Instance,"修改后的开果");
 Console.WriteLine(typeof(Property).GetProperty("A").GetValue(Instance));
 Console.ReadKey();

结果:
在这里插入图片描述
总结:

Get就是会调属性的get,Set对应是Set

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以通过反射获取new操作符定义的属性,具体步骤如下: 1. 使用Type.GetMember方法获取指定类型的成员信息,设置BindingFlags参数为BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic,这样就可以获取到该类型的所有成员,包括实例成员和静态成员,公共成员和非公共成员。 2. 遍历获取到的成员信息,判断成员是否为属性(PropertyInfo),并且该属性是否定义了new操作符。 3. 如果是,则可以通过MemberInfo.DeclaringType属性获取该属性所在的类型,即定义该属性的类型。 以下是一个示例代码: ``` using System; using System.Reflection; class BaseClass { public virtual int MyProperty { get; set; } } class DerivedClass : BaseClass { public new int MyProperty { get; set; } } class Program { static void Main(string[] args) { Type derivedType = typeof(DerivedClass); MemberInfo[] members = derivedType.GetMembers(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); foreach (MemberInfo member in members) { if (member.MemberType == MemberTypes.Property) { PropertyInfo property = (PropertyInfo)member; if (property.Name == "MyProperty" && property.DeclaringType == derivedType) { Console.WriteLine("Property {0} is defined in type {1}", property.Name, property.DeclaringType.Name); } } } } } ``` 运行该代码,输出结果为: ``` Property MyProperty is defined in type DerivedClass ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值