C# Attribute+反射的威力

先说说Attribute这个东西。

这次做需求第一次用,查找相关资料看的一脸懵逼,吐槽一手,这么简单的东西为啥要介绍的那么复杂。

Attribute叫特性,但是个人感觉把它当成标签理解更舒服点。

首先他是一个类,一个继承自System.Attribute的类。

他以[Attribute()]的形式标注在类啊,枚举啊,属性啊,方法之类上面,具体适用的对象:

[Attribute()]括弧就是这个Attribute的构造函数。

用法说完了,再说说它的作用:

先举个官方的例子,最后再说一个这次我自己用到的实例。

1、obsolete(预定义)

升级过U3D版本并且处理过Warning的同学应该对这个印象比较深刻,U3D在版本升级时通常会修改很多api(改名字或者改调用方式之类的),这时候它会用Warning告诉你,你这个api是旧的,新的要怎么怎么调。这个就是通过obsolete这个预定义的Attribute做的。

在每个方法里写LOG当然也可以实现,但是为了保持前端的一致性(比如来了新人),做该功能的人只需要在老api上加上这个“标签”就好了(后面就继续叫标签了,觉得这么理解舒服)。

2、自定义的Attribute

假如现在你手里有一堆对象,这些对象的类型不同,而且也没有共同的基类,但是它们有一个特点:这些类都实现了同一个接口。需求是,在某个地方调用这些对象的接口中的方法。

这就是Attribute登场的时候,自定义一个Attribute,给所有类实现这个方法的地方“贴上”咱们自定义的标签(在接口里贴不好使,查了官方文档,必须在具体实现的位置贴。。。),然后再调用的地方,通过反射筛选这些类的标签,然后再调用这个方法就好啦。

List<object> list = new List<object>();
MyManager myManager = new MyManager();
MineManager mineManager = new MineManager();
list.Add(myManager);
list.Add(mineManager);

假设MyManager和MineManager都实现了同一个接口,这个接口里有个Add()方法,这两个都实现了该方法,并且用MyAttribute标记过。

我们手里是List<object>队里,里面装了这两个类型的对象。

我们需要通过反射,拿到这些类中的方法信息,然后再调用这些对象的该方法即可。

for(int i = 0;i < list.Count;i++)
{
    System.Reflection.MethodInfo[] methodInfos = list[i].GetType().GetMethods();
    foreach(var methodInfo in methodInfos)
    {
        foreach(var attribute in methodInfo.GetCustomAttributes(typeof(MyAttribute),false))
        {
            MyAttribute myAttribute = attribute as MyAttribute;
            if (myAttribute != null)
            {
                methodInfo.Invoke(list[i], null);
            }
        }
    }
}

遍历该队列,拿到每个对象的Type,然后获取每个type的所有方法(因为我们的标签是加在方法上的),遍历所有方法,获取每个方法的所有Attribute,再遍历所有Attribute,找到MyAttribute类型的方法,调用就可以了(Invoke相关的不了解可以看之前的帖子)。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值