C#中Attribute的继承

时间:2022-09-20 23:55:45

在C#中Attribute是个非常有用的语法,本文不会介绍Attribute的使用方法,如果想了解Attribute的详细信息请查阅MSDN及网上相关文档。C#中的Attribute有两个地方是和继承相关的,一个地方是AttributeUsageAttribute类中的属性参数Inherited,另一个地方是Type反射中的GetCustomAttributes方法(包括Type.GetCustomAttributes、MemberInfo.GetCustomAttributes等反射方法)的inherit参数,这两个与继承相关的参数都是bool类型,但是代表的含义却不相同,我们来看看他们分别代表的是什么:

AttributeUsageAttribute类的Inherited属性参数

AttributeUsage中的属性参数Inherited指的是继承链中的子类和子类成员是否能继承在父类和父类成员上声明的Attribute。我们来看个例子,假如现在我们有两个类BaseClass和MyClass,其中MyClass继承于BaseClass,现在我们在BaseClass上声明一个自定义Attribute叫MyAttribute,代码如下:

[My]
class BaseClass
{ } class MyClass:BaseClass
{ }

如果像下面代码中设置MyAttribute上AttributeUsage的属性参数Inherited为true,则代表MyAttribute是可以被继承声明的,也就是说上面代码中在父类BaseClass上声明了MyAttribute后,子类MyClass相当于也声明了MyAttribute。

[AttributeUsage(AttributeTargets.All, Inherited = true)]
class MyAttribute : Attribute
{
}

如果像下面代码中设置MyAttribute上AttributeUsage的属性参数Inherited为false,那么代表MyAttribute是无法被继承声明的,也就是说上面代码中在父类BaseClass上声明了MyAttribute后,子类MyClass不具有MyAttribute,相当于父类BaseClass声明了MyAttribute但是子类MyClass没有声明MyAttribute。

[AttributeUsage(AttributeTargets.All, Inherited = false)]
class MyAttribute : Attribute
{
}

GetCustomAttributes方法的inherit参数

GetCustomAttributes方法中inherit参数指的是当调用GetCustomAttributes方法时,GetCustomAttributes方法是否搜索子类和子类成员上从父类继承的Attribute。同样我们来看个例子,假如现在我们有两个类BaseClass和MyClass,其中MyClass继承于BaseClass,现在我们在BaseClass上声明一个自定义Attribute叫MyAttribute,代码如下:

[My]
class BaseClass
{ } class MyClass:BaseClass
{ }

我们在MyAttribute上设置AttributeUsage的属性参数Inherited为true,那么相当于子类MyClass上也声明了MyAttribute:

[AttributeUsage(AttributeTargets.All, Inherited = true)]
class MyAttribute : Attribute
{
}

现在如果我们调用构造函数构造一个MyClass对象,然后调用对象的反射方法GetCustomAttributes看是否能在MyClass上找到MyAttribute。如果找到了则在控制台输出找到了MyAttribute,否则输出没有找到。
首先我们调用GetCustomAttributes方法时将参数inherit设置为true。结果控制台显示:"MyAttribute found!",说明GetCustomAttributes方法成功找到了MyAttribute。

var my = new MyClass();
var myMyAttribute = my.GetType().GetCustomAttributes(typeof(MyAttribute), true); if (myMyAttribute != null && myMyAttribute.Count() > )
{
Console.WriteLine("MyAttribute found!");
}
else
{
Console.WriteLine("MyAttribute not found!");
}

接着我们调用GetCustomAttributes方法时将参数inherit设置为false。这次控制台显示:"MyAttribute not found!",说明将参数inherit设置为false后GetCustomAttributes方法无法在MyClass上找到MyAttribute了。

var my = new MyClass();
var myMyAttribute = my.GetType().GetCustomAttributes(typeof(MyAttribute), false); if (myMyAttribute != null && myMyAttribute.Count() > )
{
Console.WriteLine("MyAttribute found!");
}
else
{
Console.WriteLine("MyAttribute not found!");
}

这说明GetCustomAttributes方法的inherit参数实际上就是在指示是否去搜索从父类继承来的Attribute,由于本例中的MyAttribute是声明在父类BaseClass上的,所以当在子类MyClass的反射中调用GetCustomAttributes(typeof(MyAttribute), false)时,GetCustomAttributes方法将不会去搜索从父类继承的Attribute,所以在控制台上显示MyClass上无法找到MyAttribute。但是如果在子类MyClass的反射中调用GetCustomAttributes(typeof(MyAttribute), true),那么GetCustomAttributes方法不光会搜索子类MyClass自己声明的Attribute还会去搜索从父类BaseClass继承的Attribute,由于父类BaseClass上声明了MyAttribute,所以GetCustomAttributes方法在子类MyClass上也能找到MyAttribute,最后在控制台上显示在MyClass上找到了MyAttribute。如果将MyAttribute声明在子类MyClass上而不是像本例代码一样声明在父类BaseClass上,那么在调用GetCustomAttributes(typeof(MyAttribute), false)时,就会显示在MyClass上找到MyAttribute了。

总结一下,我们可以看到AttributeUsageAttribute类的Inherited属性参数和GetCustomAttributes方法的inherit参数代表的含义是不一样的。AttributeUsageAttribute类的Inherited属性代表的是父类或父类成员上声明的Attribute是否能够被应用到继承链中子类或子类成员上去。而GetCustomAttributes方法的inherit参数代表的是调用GetCustomAttributes方法时是否去搜索继承链中从父类或父类成员继承下来的Attribute。

C#中Attribute的继承的更多相关文章

  1. JS中的原型继承机制

    转载 http://blog.csdn.net/niuyongjie/article/details/4810835 在学习JS的面向对象过程中,一直对constructor与prototype感到很 ...

  2. C#中是否可以继承String类

    C#中是否可以继承String类? 答:String类是sealed类故不可以继承. 当对一个类应用 sealed 修饰符时,此修饰符会阻止其他类从该类继承. 在下面的示例中,类 HoverTree ...

  3. 理解JavaScript中的原型继承(2)

    两年前在我学习JavaScript的时候我就写过两篇关于原型继承的博客: 理解JavaScript中原型继承 JavaScript中的原型继承 这两篇博客讲的都是原型的使用,其中一篇还有我学习时的错误 ...

  4. C#中事件的继承

    C#中的子类无法调用父类的事件,可以通过在父类中创建一个方法来调用父类的事件,而子类通过调用父类的方法来触发事件. class parent { protected string name; publ ...

  5. C++中的虚继承 & 重载隐藏覆盖的讨论

    虚继承这个东西用的真不多.估计也就是面试的时候会用到吧.. 可以看这篇文章:<关于C++中的虚拟继承的一些总结> 虚拟基类是为解决多重继承而出现的. 如:类D继承自类B1.B2,而类B1. ...

  6. python中使用多继承

    python中使用多继承,会涉及到查找顺序(MRO).重复调用(钻石继承,也叫菱形继承问题)等 MRO MRO即method resolution order,用于判断子类调用的属性来自于哪个父类.在 ...

  7. Django中的Model继承

    Django 中的 model 继承和 Python 中的类继承非常相似,只不过你要选择具体的实现方式:让父 model 拥有独立的数据库:还是让父 model 只包含基本的公共信息,而这些信息只能由 ...

  8. 《Swift Programming Language 》——Swift中怎样使用继承(Inheritance)

    一个类能够继承(inherit)还有一个类的方法(methods),属性(property)和其他特性.当一个类继承其他类时,继承类叫子类(subclass),被继承类叫超类(或父类,supercla ...

  9. javascript中的原型继承

    在Javascript面向对象编程中,原型继承不仅是一个重点也是一个不容易掌握的点.在本文中,我们将对Javascript中的原型继承进行一些探索. 基本形式 我们先来看下面一段代码: <cod ...

随机推荐

  1. 第一次写jquery插件,来个countdown计时器吧

    之前同学做个购物商城秒杀活动需要计时器的功能,在用jquery提供的countdown插件时,一直报错,貌似还需要依赖除jquery之外的其他插件,搞了半天也没搞成功,就叫我帮忙写个.然而我并没有写过 ...

  2. C&num;&period;NET 大型通用信息化系统集成快速开发平台 4&period;0 版本 - 多系统开发接口 - 苹果客户端开发接口

    最近工作上需要,给苹果客户端开发接口,实现集中统一的用户管理,下面是接口调用参考. 1: 获取OpenId? http://127.0.0.1/GetOpenId.ashx?username=Admi ...

  3. mysql 5&period;7 win7 压缩版安装

    1.下载mysql压缩版并解压: 2.复制my-defualt.ini , 命名为my.ini; 3. 3.1 运行在下图bin目录下运行:mysqld --install   安装mysql服务: ...

  4. Swift语言实战晋级-第9章 游戏实战-跑酷熊猫-1

    学习目标 一.进一步学习Swift的游戏制作 二.掌握SKNode,SKSpriteNode的运用 三.了解SpriteKit的物理系统 四.掌握动作(SKAction)的运用 在这一章,我们要通过制 ...

  5. drupal 做301跳转(删除url里的www)&comma; 关键代码 可用到任何网站

    //hook_init(); function ex_init(){ //删除 url 前面的 www if (substr($_SERVER['HTTP_HOST'],0,3) == 'www'){ ...

  6. ACE&lowbar;linux:任务 &amp&semi; 命令(Task and Command)

    1.涉及类 ACE_Task//ACE任务ACE_Activation_Queue//ACE命令队列 ACE_Method_Request//ACE请求(命令) 2.简介 ACE主动对象模式 主动对象 ...

  7. PHP个人常用函数封装

    function GetIP(){ if(!empty($_SERVER["HTTP_CLIENT_IP"])){ $cip = $_SERVER["HTTP_CLIEN ...

  8. 为Android内核添加新驱动

    转载地址:http://blog.chinaunix.net/uid-16759545-id-4892379.html 1. 在drives目录下添加hello目录,内含hello.c Kconfig ...

  9. Neo4j安装后的密码修改

    首先默认用户名/密码是neo4j/neo4j. 在安全验证打开的时候,你访问服务器/db/data之类的地址可能会提示您以下信息: { "password_change" : &q ...

  10. JS如何创建对象

    js创建对象的方法很多,以下分别介绍