您的位置:首页 > 其它

.net中的特性

2014-05-07 10:52 155 查看
本文来之:http://hi.baidu.com/sanlng/item/afa31eed0a383e0e570f1d3e

在一般的应用中,特性(Attribute,以称为属性)好像被使用的不是很多。其实特性是一个很有用的东西,也是.net的一个重要组成部分。

1、特性是什么?

特性是一种向类添加代码的方法,这些代码以声明的形式来修饰程序集、类以及其它代码元素。这种修饰类似于public、private等关键字对一个方法的修饰,与之不同的是,多数特性并不与特定的语言相关,所以在使用特性时可以在不需要改变编译器的情况下扩展语言功能。

2、特性有什么用

特性是.net中一个重要的组成部分,.net在很多地方都使用了特性,见下面的文字。

在 XML Web services 中,使用 WebMethod 特性标记方法,以指示该方法应可通过 SOAP 协议进行调用。有关更多信息,请参见 WebMethodAttribute 类

描述当与本机代码进行交互操作时如何封送方法参数。有关更多信息,请参见 MarshalAsAttribute 类

描述类、方法和接口的 COM 属性。

将组件标记为 COM,以便 Visual Basic 编译器生成创建 COM 组件所需的附加代码。有关更多信息,请参见 ComClassAttribute 类

使用 DllImportAttribute 类调用非托管代码。

在标题、版本、说明或商标方面描述您的程序集。

描述要持久性序列化类的哪些成员。

描述如何映射类成员和 XML 节点以便进行 XML 序列化。

描述方法的安全要求。

指定用于强制安全性的特性。

由实时 (JIT) 编译器控制优化,以便易于调试代码。
以上文字来自MSDN。网址:

http://msdn.microsoft.com/library/chs/default.asp?url=/library/CHS/vbcn7/html/vaconcommonusesforattributes.asp

3、C#中的特性类

C#中的所有特性的基类都是Attribute的子类。特性在使用的时候不同于一般的类。特性在使用的时候需要将其与某种代码元素(如一个类或一个方法)关联起来,并且只有在特性被搜索到时才能实例化和使用。还有有趣的一点是,特性的添加并不会为你的程序添加任何可执行代码,程序在编译时只是将其添加程序集里,所以如果你想使用元数据中的某个特性,那你就得先去搜索。

4、如何使用特性

●使用系统特性类

Obsolete特性

该特性用于标识不再使用的代码元素,见下面的代码(代码片断1)

[Obsolete("该方法将在下一版中被删除")]
public string ReturnValue(string OutValue)
{
return OutValue ;
}


(代码片断1)

ReturnValue()方法被Obsolete进行标记,这样当包含这个方法的类被实例化且该方法被调用时,编译器将给出警告信息,但程序依旧可以执行。

因为特性是一个类,所以其拥有构造函数,并且还可能具有被重载了的带参数的构造函数,下面的代码使用了带有两个参数的特性构造函数

[Obsolete("该方法将在下一版中被删除",false)]
public string ReturnValue(string OutValue)
{
return OutValue ;
}


(代码片断2)

Obsolete的这个构造函数中的第二个参数用于表示在编译器编译时是否将过时代码视为错误,我们这里将其指定为false,即不视为错误处理。如果将其指定为true,则对过时方法的调用将引发异常,程序不能被编译。如下代码

[Obsolete("该方法将在下一版中被删除",true)]
public string ReturnValue(string OutValue)
{
return OutValue ;
}


(代码片断3)

前面讲到过,特性只有被专门的特性搜索工具搜索到之后才能实例化和使用,Obsolete特性由编译器搜索检查并搜索,其它一些特性则由.net架框中的类进行检查和搜索。

.net中还有大量的特性可供使用,如控制对象序列化、标识Web Service之类的特性。按照惯例,.net中,所有的特性其类名都是以Attribute结尾的,包括编译器在搜索一个特性时如果没有找到,会自动在该特性名之后加上Attribute继续搜索。

●自定义特性类

下面我们将自己定义一个特性。定义一个特性与定义一个类没有什么区别,我们只需要指定其从Attribute基继承即可。下面的代码定义了一个特性,该特性用于指定一个代码元素的作者、电话以及该元素的注释内容

namespace MyClass
{
/// <summary>
/// 标记一个类的作者、注释与电话
/// </summary>
[AttributeUsage(AttributeTargets.Method)]
public class AuthorAttribute : Attribute
{
private string _Name;

private string _Note;

private string _Tel;

public AuthorAttribute()
{
//
// TODO: 在此处添加构造函数逻辑
//
}

public AuthorAttribute(string Name)
{
_Name = Name;
}

/// <summary>
/// 用于获取或设置代码元素的作者
/// </summary>
public string Name
{
get
{
return _Name;
}
set
{
_Name = value;
}
}

/// <summary>
/// 用于获取或设置代码元素的注释
/// </summary>
public string Note
{
get
{
return _Note;
}
set
{
_Note = value;
}
}

/// <summary>
/// 用于获取或设置代码元素作者的电话
/// </summary>
public string Tel
{
get
{
return _Tel;
}
set
{
_Tel = value;
}
}

/// <summary>
/// 用于获取对代码元素的注释
/// </summary>
/// <returns></returns>
public string GetNote()
{
if (_Note == null)
{
return "没有添加任何注释!";
}
else
{
return _Note;
}
}
}
}


View Code

(代码片断10)

然后,我们(代码片断10)上面定义的特性应用到一个方法之上。

[Author("henry")]
public string MemberInfo(string OutValue)
{
return "该会员名称:" + _Name + ";该会员所属国家:" + _Country ;
}


(代码片断11)

你可以尝试将该特性应用到一个属性会出现什么样的结果。

[AttributeUsage(AttributeTargets.Method)]在使用的时候还可以用“|”将几个不同的AttributeTargets枚举隔开,如

[AttributeUsage(AttributeTargets.Method|AttributeTargets.Property)]

这样,这个特性就可以在属性与方法上同时使用了,如果将AttributeTargets设置为All,则允许这个特性在程序的任何元素上使用。

在默认情况下,特性是不能被子类继承的,如果需要让一个特性可以被子类继承,则需要将AttributeUsage特性的Inherited设置为true,如下代码

[AttributeUsage(AttributeTargets.All,Inherited=true)]

这样,自定义特性将可以被任何程序元素使用,且允许子类继承。

AllowMultiple允许一个特性可被多次的应用到一个代码元素上。但在默认情况下,这是不允许的。见下面的代码

[AttributeUsage(AttributeTargets.ALL,AllowMultiple=true)]

然后在Member类的MemberInfo()应用该特性

[Author("Tom")]
[Author("henry")]
public string MemberInfo(string OutValue)
{
return "该会员名称:" + _Name + ";该会员所属国家:" + _Country ;
}


只能写到这里了,我也很少用这个东西,希望可以与高手一起交流。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: