前端之家收集整理的这篇文章主要介绍了
一、特性是什么东东,
前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
前言
我们初学C#的时候看到类上面一对中括号里面有个高亮了的关键字,不知道那是什么有什么用。想问人又不知道它叫什么。纠结的要命。其实,它就是特性。如:

这就是我们今天要分析的主题。
特性是什么?
个人理解,特性就是修饰对象元数据的修饰符。
那么什么是“元数据”?
元数据就是用来描述数据的数据。

图中的1.是特性 2.是访问修饰符 3.声明修饰符 4.数据类型 5.变量名 6.变量数据值,其中1、2、3、4、5就是元数据,用来描述数据(6)的数据。
特性到底是什么?
如上面的 ,会不会也是一个如 这样类似的修饰符呢,我们且看看反编译后的中间语言。

意料之外,我们看到了上面的2、3、4、5,而1
然后我们接着在vs里面把光标移到 上按F12,如:

原来只是一个继承了 的一个类 类的实例化了。
我们自定义一个特性玩玩
我们看到上面系统特性 上面还有特性,如:Serializable、AttributeUsage、Camvisible等。像这种特性我们称之为“元数据的元数据”(元元数据)。
1.我们分别来解释性上面的三个特性。
Serializable:表示类型支持序列化。
ComVisible:微软定义“控制程序集中个别托管类型、 成员或所有类型对COM的可访问性”。
AttributeUsage:这个比较重要了,基本上每个特性定义都用到了它。它就是用来表示当前这个特性可用于哪些对象。如:类、方法、属性...等等。(自定义特性了)
2.上面有个问题,不知道大家发现没有。
就是我们特性名明明是 ,为什么我们F12进去后变成了 呢?这其实只是一个微软的约定而已,没有为什么。
其实我们可以两种写法: )] 和 )] 是等效的,只是我们一般都用后面这种。
3.定义的特性必须继承于 。
4.属性没有set方法。只能通过构造函数赋值。属性,所以全部的设置都在后面的小括号里进行的。属性,我们就要用到,下面会继续讲到
好了,我们通过这四点完全可以自己定义个特性来玩玩了。我们来定义一个给机器看的注释。我们平时的注释都只是给程序员看的,编译之后就全没了。那我们想在代码运行时,弹出我们的注释怎么办,接下来我们用自定义特性来实现,如:
[AttributeUsage(AttributeTargets.All)]
TMessgAttribute : Attribute加上后缀TMessgAttribute 2.继承Attribute。
</span><span style="color: #808080;">///</span> <span style="color: #808080;"><param name="createTime"></span><span style="color: #008000;">创建时间</span><span style="color: #808080;"></param></span>
<span style="color: #808080;">///</span> <span style="color: #808080;"><param name="createName"></span><span style="color: #008000;">创建人</span><span style="color: #808080;"></param></span>
<span style="color: #0000ff;">public</span> TMessgAttribute(<span style="color: #0000ff;">string</span> createTime,<span style="color: #0000ff;">string</span> createName,<span style="color: #0000ff;">string</span><span style="color: #000000;"> mess)
{
</span><span style="color: #0000ff;">this</span>._createName =<span style="color: #000000;"> createName;
</span><span style="color: #0000ff;">this</span>._createTime =<span style="color: #000000;"> createTime;
</span><span style="color: #0000ff;">this</span>._mess =<span style="color: #000000;"> mess;
}
</span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">string</span><span style="color: #000000;"> _createTime;
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span><span style="color: #000000;"> createTime
{
</span><span style="color: #0000ff;">get</span> { <span style="color: #0000ff;">return</span> _createTime; }<span style="color: #008000;">//</span><span style="color: #008000;">4.只能有get<a href="/tag/fangfa/" target="_blank" class="keywords">方法</a></span>
<span style="color: #000000;"> }
<span style="color: #0000ff;">private <span style="color: #0000ff;">string<span style="color: #000000;"> _createName;
<span style="color: #0000ff;">public <span style="color: #0000ff;">string<span style="color: #000000;"> createName
{
<span style="color: #0000ff;">get { <span style="color: #0000ff;">return<span style="color: #000000;"> _createName; }
}
<span style="color: #0000ff;">private <span style="color: #0000ff;">string<span style="color: #000000;"> _mess;
<span style="color: #0000ff;">public <span style="color: #0000ff;">string mess { <span style="color: #0000ff;">get { <span style="color: #0000ff;">return<span style="color: #000000;"> _mess; } }
}
好了,上面就是我们自定义的特性。那我们怎样使用呢。和系统特性一样。我们先定义一个测试类TClass,然后在类上面定义特性,如:
[TMessg(,,自定义特性,不要报错哦,求求你了。
}
我们定义了特性,也使用了特性,然我们却不知道怎么看效果。我们想看到效果怎么办。可以使用反射)看看 类的元数据,如:
Main(= (TClass);
TMessgAttribute hobbyAttr = (TMessgAttribute)Attribute.GetCustomAttribute(info,
打印效果如:

什么是命名参数?
上面的自定义特性都是通过构造函数设置字段私有字段,然后通过只提供了get的属性来访问。那么可否直接在特性里面定义拥有get和set的属性吗?答案是肯定的。那怎么在使用特性的时候设置这个属性呢?我们接着往下看。
我们接着在自定义特性里面添加一个属性。
modifyTime { ; ; }
使用自定义特性。
[TMessg(,,modifyTime =
}
我们发现,直接在输入了构造函数之后接着设置属性就可以。()
这种参数,我们成为命名参数。
我们来继续要看看AttributeUsage()
我们F12看看AttributeUsage的定义

看上去,同样也只是普通的特性。实际上也只是个普通的特性。>_<
我们来看看他的这几个属性是干嘛的。从最后一个开始看。
1.AttributeTargets,我们在上面其实就已经看到并也已经使用了。

我们设置的是可用于所有对象。AttributeTargets其实是个枚举,每个值对于一个类型对象。
你可以直接在 F12进去:

2.Inherited:“”
如下,我们设置 那么继承TClass的T2Class无法访问到TClass中设置的特性元数据。
= )]
TMessgAttribute : Attribute
</span><span style="color: #808080;">///</span> <span style="color: #808080;"><param name="createTime"></span><span style="color: #008000;">创建时间</span><span style="color: #808080;"></param></span>
<span style="color: #808080;">///</span> <span style="color: #808080;"><param name="createName"></span><span style="color: #008000;">创建人</span><span style="color: #808080;"></param></span>
<span style="color: #0000ff;">public</span> TMessgAttribute(<span style="color: #0000ff;">string</span> createTime,<span style="color: #0000ff;">string</span><span style="color: #000000;"> mess)
{
</span><span style="color: #0000ff;">this</span>._createName =<span style="color: #000000;"> createName;
</span><span style="color: #0000ff;">this</span>._createTime =<span style="color: #000000;"> createTime;
</span><span style="color: #0000ff;">this</span>._mess =<span style="color: #000000;"> mess;
}
</span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">string</span><span style="color: #000000;"> _createTime;
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span><span style="color: #000000;"> createTime
{
</span><span style="color: #0000ff;">get</span> { <span style="color: #0000ff;">return</span> _createTime; }<span style="color: #008000;">//</span><span style="color: #008000;">4.只能有get方法</span>
<span style="color: #000000;"> }
<span style="color: #0000ff;">private <span style="color: #0000ff;">string<span style="color: #000000;"> _createName;
<span style="color: #0000ff;">public <span style="color: #0000ff;">string<span style="color: #000000;"> createName
{
<span style="color: #0000ff;">get { <span style="color: #0000ff;">return<span style="color: #000000;"> _createName; }
}
<span style="color: #0000ff;">private <span style="color: #0000ff;">string<span style="color: #000000;"> _mess;
<span style="color: #0000ff;">public <span style="color: #0000ff;">string mess { <span style="color: #0000ff;">get { <span style="color: #0000ff;">return<span style="color: #000000;"> _mess; } }
<span style="color: #808080;">/// <span style="color: #808080;">
<span style="color: #808080;">///<span style="color: #008000;"> 修改时间
<span style="color: #808080;">/// <span style="color: #808080;">
<span style="color: #0000ff;">public <span style="color: #0000ff;">string modifyTime { <span style="color: #0000ff;">get; <span style="color: #0000ff;">set<span style="color: #000000;">; }
}
</span><span style="color: #0000ff;">class</span><span style="color: #000000;"> Program
{
</span><span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> Main(<span style="color: #0000ff;">string</span><span style="color: #000000;">[] args)
{
System.Reflection.MemberInfo info </span>= <span style="color: #0000ff;">typeof</span>(T2Class); <span style="color: #008000;">//</span><span style="color: #008000;">通过反射得到TClass类的信息</span>
TMessgAttribute hobbyAttr = (TMessgAttribute)Attribute.GetCustomAttribute(info,<span style="color: #0000ff;">typeof</span><span style="color: #000000;">(TMessgAttribute));
Console.WriteLine(</span><span style="color: #800000;">"</span><span style="color: #800000;">类名:{0}</span><span style="color: #800000;">"</span><span style="color: #000000;">,info.Name);
</span><span style="color: #0000ff;">if</span> (hobbyAttr != <span style="color: #0000ff;">null</span><span style="color: #000000;">)
{
Console.WriteLine(</span><span style="color: #800000;">"</span><span style="color: #800000;">创建时间:{0}</span><span style="color: #800000;">"</span><span style="color: #000000;">,hobbyAttr.createTime);
Console.WriteLine(</span><span style="color: #800000;">"</span><span style="color: #800000;">创建人:{0}</span><span style="color: #800000;">"</span><span style="color: #000000;">,hobbyAttr.createName);
Console.WriteLine(</span><span style="color: #800000;">"</span><span style="color: #800000;">备注消息:{0}</span><span style="color: #800000;">"</span><span style="color: #000000;">,hobbyAttr.mess);
Console.WriteLine(</span><span style="color: #800000;">"</span><span style="color: #800000;">修改时间:{0}</span><span style="color: #800000;">"</span><span style="color: #000000;">,hobbyAttr.modifyTime);
}
Console.ReadKey();
}
}
[TMessg(</span><span style="color: #800000;">"</span><span style="color: #800000;">2015-12-20</span><span style="color: #800000;">"</span>,modifyTime = <span style="color: #800000;">"</span><span style="color: #800000;">2015-12-21</span><span style="color: #800000;">"</span><span style="color: #000000;">)]
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> TClass
{
</span><span style="color: #008000;">//</span><span style="color: #008000;">................</span>
<span style="color: #000000;"> }
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> T2Class : TClass
{
</span><span style="color: #008000;">//</span><span style="color: #008000;">...........</span>
<span style="color: #000000;"> }
}
<span style="color: #0000ff;">namespace<span style="color: #000000;"> net
{
[AttributeUsage(AttributeTargets.All,Inherited = <span style="color: #0000ff;">true,AllowMultiple = <span style="color: #0000ff;">true)]<span style="color: #008000;">//<span style="color: #008000;">3.设置可用于哪些对象
<span style="color: #0000ff;">public <span style="color: #0000ff;">class TMessgAttribute : Attribute<span style="color: #008000;">//<span style="color: #008000;">1.定义类TMessg加上后缀TMessgAttribute 2.继承Attribute。
<span style="color: #000000;"> {
<span style="color: #0000ff;">public<span style="color: #000000;"> TMessgAttribute() { }
</span><span style="color: #808080;">///</span> <span style="color: #808080;"><param name="createTime"></span><span style="color: #008000;">创建时间</span><span style="color: #808080;"></param></span>
<span style="color: #808080;">///</span> <span style="color: #808080;"><param name="createName"></span><span style="color: #008000;">创建人</span><span style="color: #808080;"></param></span>
<span style="color: #0000ff;">public</span> TMessgAttribute(<span style="color: #0000ff;">string</span> createTime,<span style="color: #0000ff;">string</span><span style="color: #000000;"> mess)
{
</span><span style="color: #0000ff;">this</span>._createName =<span style="color: #000000;"> createName;
</span><span style="color: #0000ff;">this</span>._createTime =<span style="color: #000000;"> createTime;
</span><span style="color: #0000ff;">this</span>._mess =<span style="color: #000000;"> mess;
}
</span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">string</span><span style="color: #000000;"> _createTime;
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span><span style="color: #000000;"> createTime
{
</span><span style="color: #0000ff;">get</span> { <span style="color: #0000ff;">return</span> _createTime; }<span style="color: #008000;">//</span><span style="color: #008000;">4.只能有get方法</span>
<span style="color: #000000;"> }
<span style="color: #0000ff;">private <span style="color: #0000ff;">string<span style="color: #000000;"> _createName;
<span style="color: #0000ff;">public <span style="color: #0000ff;">string<span style="color: #000000;"> createName
{
<span style="color: #0000ff;">get { <span style="color: #0000ff;">return<span style="color: #000000;"> _createName; }
}
<span style="color: #0000ff;">private <span style="color: #0000ff;">string<span style="color: #000000;"> _mess;
<span style="color: #0000ff;">public <span style="color: #0000ff;">string mess { <span style="color: #0000ff;">get { <span style="color: #0000ff;">return<span style="color: #000000;"> _mess; } }
<span style="color: #808080;">/// <span style="color: #808080;">
<span style="color: #808080;">///<span style="color: #008000;"> 修改时间
<span style="color: #808080;">/// <span style="color: #808080;">
<span style="color: #0000ff;">public <span style="color: #0000ff;">string modifyTime { <span style="color: #0000ff;">get; <span style="color: #0000ff;">set<span style="color: #000000;">; }
}
</span><span style="color: #0000ff;">class</span><span style="color: #000000;"> Program
{
</span><span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> Main(<span style="color: #0000ff;">string</span><span style="color: #000000;">[] args)
{
System.Reflection.MemberInfo info </span>= <span style="color: #0000ff;">typeof</span><span style="color: #000000;">(T2Class);
TMessgAttribute[] hobbyAttr </span>= (TMessgAttribute[])Attribute.GetCustomAttributes(info,<span style="color: #0000ff;">typeof</span>(TMessgAttribute));<span style="color: #008000;">//</span><span style="color: #008000;">修改1.这里需要取特性数据的集合了</span>
Console.WriteLine(<span style="color: #800000;">"</span><span style="color: #800000;">类名:{0}</span><span style="color: #800000;">"</span><span style="color: #000000;">,info.Name);
</span><span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> i = <span style="color: #800080;">0</span>; i < hobbyAttr.Count(); i++)<span style="color: #008000;">//</span><span style="color: #008000;">修改2.这里需要循环打印了</span>
<span style="color: #000000;"> {
Console.WriteLine(<span style="color: #800000;">"<span style="color: #800000;">================================================<span style="color: #800000;">"<span style="color: #000000;">);
Console.WriteLine(<span style="color: #800000;">"<span style="color: #800000;">创建人:{0}<span style="color: #800000;">"<span style="color: #000000;">,hobbyAttr[i].createName);
Console.WriteLine(<span style="color: #800000;">"<span style="color: #800000;">创建时间:{0}<span style="color: #800000;">"<span style="color: #000000;">,hobbyAttr[i].createTime);
Console.WriteLine(<span style="color: #800000;">"<span style="color: #800000;">备注消息:{0}<span style="color: #800000;">"<span style="color: #000000;">,hobbyAttr[i].mess);
Console.WriteLine(<span style="color: #800000;">"<span style="color: #800000;">修改时间:{0}<span style="color: #800000;">"<span style="color: #000000;">,hobbyAttr[i].modifyTime);
}
Console.ReadKey();
}
}
[TMessg(</span><span style="color: #800000;">"</span><span style="color: #800000;">2015-12-20</span><span style="color: #800000;">"</span>,modifyTime = <span style="color: #800000;">"</span><span style="color: #800000;">2015-12-21</span><span style="color: #800000;">"</span><span style="color: #000000;">)]
[TMessg(</span><span style="color: #800000;">"</span><span style="color: #800000;">2015-12-21</span><span style="color: #800000;">"</span>,<span style="color: #800000;">"</span><span style="color: #800000;">我再次测试,还能给我面子显示出来吗?</span><span style="color: #800000;">"</span>,modifyTime = <span style="color: #800000;">"</span><span style="color: #800000;">2015-12-22</span><span style="color: #800000;">"</span><span style="color: #000000;">)]
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> TClass
{
</span><span style="color: #008000;">//</span><span style="color: #008000;">................</span>
<span style="color: #000000;"> }
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> T2Class : TClass
{
</span><span style="color: #008000;">//</span><span style="color: #008000;">...........</span>
<span style="color: #000000;"> }
}