Attribute在net编程中的应用.docx

上传人:b****5 文档编号:6245871 上传时间:2023-01-04 格式:DOCX 页数:36 大小:32.32KB
下载 相关 举报
Attribute在net编程中的应用.docx_第1页
第1页 / 共36页
Attribute在net编程中的应用.docx_第2页
第2页 / 共36页
Attribute在net编程中的应用.docx_第3页
第3页 / 共36页
Attribute在net编程中的应用.docx_第4页
第4页 / 共36页
Attribute在net编程中的应用.docx_第5页
第5页 / 共36页
点击查看更多>>
下载资源
资源描述

Attribute在net编程中的应用.docx

《Attribute在net编程中的应用.docx》由会员分享,可在线阅读,更多相关《Attribute在net编程中的应用.docx(36页珍藏版)》请在冰豆网上搜索。

Attribute在net编程中的应用.docx

Attribute在net编程中的应用

Attribute在.net编程中的应用

Attribute在.net编程中的应用

(一)

Attribute的基本概念

经常有朋友问,Attribute是什么?

它有什么用?

好像没有这个东东程序也能运行。

实际上在.Net中,Attribute是一个非常重要的组成部分,为了帮助大家理解和掌握Attribute,以及它的使用方法,特地收集了几个Attribute使用的例子,提供给大家参考。

在具体的演示之前,我想先大致介绍一下Attribute。

我们知道在类的成员中有property成员,二者在中文中都做属性解释,那么它们到底是不是同一个东西呢?

从代码上看,明显不同,首先就是它们的在代码中的位置不同,其次就是写法不同(Attribute必须写在一对方括符中)。

什么是Atrribute

首先,我们肯定Attribute是一个类,下面是msdn文档对它的描述:

公共语言运行时允许你添加类似关键字的描述声明,叫做attributes,它对程序中的元素进行标注,如类型、字段、方法和属性等。

Attributes和Microsoft.NETFramework文件的元数据保存在一起,可以用来向运行时描述你的代码,或者在程序运行的时候影响应用程序的行为。

在.NET中,Attribute被用来处理多种问题,比如序列化、程序的安全特征、防止即时编译器对程序代码进行优化从而代码容易调试等等。

下面,我们先来看几个在.NET中标准的属性的使用,稍后我们再回过头来讨论Attribute这个类本身。

(文中的代码使用C#编写,但同样适用所有基于.NET的所有语言)

Attribute作为编译器的指令

在C#中存在着一定数量的编译器指令,如:

#defineDEBUG,#undefineDEBUG,#if等。

这些指令专属于C#,而且在数量上是固定的。

而Attribute用作编译器指令则不受数量限制。

比如下面的三个Attribute:

∙Conditional:

起条件编译的作用,只有满足条件,才允许编译器对它的代码进行编译。

一般在程序调试的时候使用。

∙DllImport:

用来标记非.NET的函数,表明该方法在一个外部的DLL中定义。

∙Obsolete:

这个属性用来标记当前的方法已经被废弃,不再使用了。

下面的代码演示了上述三个属性的使用:

#defineDEBUG//这里定义条件

usingSystem;

usingSystem.Runtime.InteropServices;

usingSystem.Diagnostics;

namespaceAttributeDemo

{

classMainProgramClass

{

[DllImport("User32.dll")]

publicstaticexternintMessageBox(inthParent,stringMessage,stringCaption,intType);

staticvoidMain(string[]args)

{

DisplayRunningMessage();

DisplayDebugMessage();

MessageBox(0,"Hello","Message",0);

Console.ReadLine();

}

[Conditional("DEBUG")]

privatestaticvoidDisplayRunningMessage()

{

Console.WriteLine("开始运行Main子程序。

当前时间是"+DateTime.Now);

}

[Conditional("DEBUG")]

[Obsolete]

privatestaticvoidDisplayDebugMessage()

{

Console.WriteLine("开始Main子程序");

}

}

}

如果在一个程序元素前面声明一个Attribute,那么就表示这个Attribute被施加到该元素上,前面的代码,[DllImport]施加到MessageBox函数上,[Conditional]施加到DisplayRuntimeMessage方法和DisplayDebugMessage方法,[Obsolete]施加到DisplayDebugMessage方法上。

根据上面涉及到的三个Attribute的说明,我们可以猜到程序运行的时候产生的输出:

DllImportAttribute表明了MessageBox是User32.DLL中的函数,这样我们就可以像内部方法一样调用这个函数。

重要的一点就是Attribute就是一个类,所以DllImport也是一个类,Attribute类是在编译的时候被实例化的,而不是像通常的类那样在运行时候才实例化。

Attribute实例化的时候根据该Attribute类的设计可以带参数,也可以不带参数,比如DllImport就带有"User32.dll"的参数。

Conditional对满足参数的定义条件的代码进行编译,如果没有定义DEBUG,那么该方法将不被编译,读者可以把#defineDEBUG一行注释掉看看输出的结果(release版本,在Debug版本中Conditional的debug总是成立的)。

Obsolete表明了DispalyDebugMessage方法已经过时了,它有一个更好的方法来代替它,当我们的程序调用一个声明了Obsolete的方法时,那么编译器会给出信息,Obsolete还有其他两个重载的版本。

大家可以参考msdn中关于的ObsoleteAttribute类的描述。

Attribute类

除了.NET提供的那些Attribute派生类之外,我们可以自定义我们自己的Attribute,所有自定义的Attribute必须从Attribute类派生。

现在我们来看一下Attribute类的细节:

protectedAttribute():

保护的构造器,只能被Attribute的派生类调用。

三个静态方法:

staticAttributeGetCustomAttribute():

这个方法有8种重载的版本,它被用来取出施加在类成员上指定类型的Attribute。

staticAttribute[]GetCustomAttributes():

这个方法有16种重载版本,用来取出施加在类成员上指定类型的Attribute数组。

staticboolIsDefined():

由八种重载版本,看是否指定类型的定制attribute被施加到类的成员上面。

实例方法:

boolIsDefaultAttribute():

如果Attribute的值是默认的值,那么返回true。

boolMatch():

表明这个Attribute实例是否等于一个指定的对象。

公共属性:

TypeId:

得到一个唯一的标识,这个标识被用来区分同一个Attribute的不同实例。

我们简单地介绍了Attribute类的方法和属性,还有一些是从object继承来的。

这里就不列出来了。

下面介绍如何自定义一个Attribute:

自定义一个Attribute并不需要特别的知识,其实就和编写一个类差不多。

自定义的Attribute必须直接或者间接地从Attribute这个类派生,如:

publicMyCustomAttribute:

Attribute{...}

这里需要指出的是Attribute的命名规范,也就是你的Attribute的类名+"Attribute",当你的Attribute施加到一个程序的元素上的时候,编译器先查找你的Attribute的定义,如果没有找到,那么它就会查找“Attribute名称"+Attribute的定义。

如果都没有找到,那么编译器就报错。

对于一个自定义的Attribute,你可以通过AttributeUsage的Attribute来限定你的Attribute所施加的元素的类型。

代码形式如下:

[AttriubteUsage(参数设置)]public自定义Attribute:

Attribute{...}

非常有意思的是,AttributeUsage本身也是一个Attribute,这是专门施加在Attribute类的Attribute.AttributeUsage自然也是从Attribute派生,它有一个带参数的构造器,这个参数是AttributeTargets的枚举类型。

下面是AttributeTargets的定义:

publicenumAttributeTargets

{

All=16383,

Assembly=1,

Module=2,

Class=4,

Struct=8,

Enum=16,

Constructor=32,

Method=64,

Property=128,

Field=256,

Event=512,

Interface=1024,

Parameter=2048,

Delegate=4096,

ReturnValue=8192

}

作为参数的AttributeTarges的值允许通过“或”操作来进行多个值得组合,如果你没有指定参数,那么默认参数就是All。

AttributeUsage除了继承Attribute的方法和属性之外,还定义了以下三个属性:

AllowMultiple:

读取或者设置这个属性,表示是否可以对一个程序元素施加多个Attribute。

Inherited:

读取或者设置这个属性,表示是否施加的Attribute可以被派生类继承或者重载。

ValidOn:

读取或者设置这个属性,指明Attribute可以被施加的元素的类型。

AttributeUsage的使用例子:

usingSystem;

namespaceAttTargsCS

{

//该Attribute只对类有效.

[AttributeUsage(AttributeTargets.Class)]

publicclassClassTargetAttribute:

Attribute

{

}

//该Attribute只对方法有效.

[AttributeUsage(AttributeTargets.Method)]

publicclassMethodTargetAttribute:

Attribute

{

}

//该Attribute只对构造器有效。

[AttributeUsage(AttributeTargets.Constructor)]

publicclassConstructorTargetAttribute:

Attribute

{

}

//该Attribute只对字段有效.

[AttributeUsage(AttributeTargets.Field)]

publicclassFieldTargetAttribute:

Attribute

{

}

//该Attribute对类或者方法有效(组合).

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

publicclassClassMethodTargetAttribute:

Attribute

{

}

//该Attribute对所有的元素有效.

[AttributeUsage(AttributeTargets.All)]

publicclassAllTargetsAttribute:

Attribute

{

}

//上面定义的Attribute施加到程序元素上的用法

[ClassTarget]//施加到类

[ClassMethodTarget]//施加到类

[AllTargets]//施加到类

publicclassTestClassAttribute

{

[ConstructorTarget]//施加到构造器

[AllTargets]//施加到构造器

TestClassAttribute()

{

}

[MethodTarget]//施加到方法

[ClassMethodTarget]//施加到方法

[AllTargets]//施加到方法

publicvoidMethod1()

{

}

[FieldTarget]//施加到字段

[AllTargets]//施加到字段

publicintmyInt;

staticvoidMain(string[]args)

{

}

}

}

 至此,我们介绍了有关Attribute类和它们的代码格式。

你一定想知道到底如何在你的应用程序中使用Attribute,如果仅仅是前面介绍的内容,还是不足以说明Attribute有什么实用价值的话,那么从后面的章节开始我们将介绍几个Attribute的不同用法,相信你一定会对Attribute有一个新的了解。

Attribute在.net编程中的应用

(二)

.NETFramework中对Attribute的支持是一个全新的功能,这种支持来自它的Attribute类。

在你的程序中适当地使用这个类,或者是灵活巧妙地利用这个类,将使你的程序获得某种在以往编程中很难做到的能力。

我们来看一个例子:

假如你是一个项目开发小组中的成员,你想要跟踪项目代码检查的信息,通常你可以把代码的检查信息保存在数据库中以便查询;或者把信息写到代码的注释里面,这样可以阅读代码的同时看到代码被检查的信息。

我们知道.NET的组件是自描述的,那么是否可以让代码自己来描述它被检查的信息呢?

这样我们既可以将信息和代码保存在一起,又可以通过代码的自我描述得到信息。

答案就是使用Attribute.

下面的步骤和代码告诉你怎么做:

首先,我们创建一个自定义的Attribute,并且事先设定我们的Attribute将施加在class的元素上面以获取一个类代码的检查信息。

usingSystem;

usingSystem.Reflection;

[AttributeUsage(AttributeTargets.Class)]//还记得上一节的内容吗?

publicclassCodeReviewAttribute:

System.Attribute//定义一个CodeReview的Attribute

{

privatestringreviewer;//代码检查人

privatestringdate;//检查日期

privatestringcomment;//检查结果信息

//参数构造器

publicCodeReviewAttribute(stringreviewer,stringdate)

{

this.reviewer=reviewer;

this.date=date;

}

publicstringReviewer

{

get

{

returnreviewer;

}

}

publicstringDate

{

get

{

returndate;

}

}

publicstringComment

{

get

{

returncomment;

}

set

{

comment=value;

}

}

}

我们的自定义CodeReviewAttribute同普通的类没有区别,它从Attribute派生,同时通过AttributeUsage表示我们的Attribute仅可以施加到类元素上。

第二步就是使用我们的CodeReviewAttribute,假如我们有一个Jack写的类MyClass,检查人Niwalker,检查日期2003年7月9日,于是我们施加Attribute如下:

[CodeReview("Niwalker","2003-7-9",Comment="Jack的代码")]

publicclassMyClass

{

//类的成员定义

}

当这段代码被编译的时候,编译器会调用CodeReviewAttribute的构造器并且把"Niwalker"和"2003-7-9"分别作为构造器的参数。

注意到参数表中还有一个Comment属性的赋值,这是Attribute特有的方式,这里你可以设置更多的Attribute的公共属性(如果有的话),需要指出的是.NETFramework1.0允许向private的属性赋值,但在.NETFramework1.1已经不允许这样做,只能向public的属性赋值。

第三步就是取出我们需要的信息,这是通过.NET的反射来实现的,关于反射的知识,限于篇幅我不打算在这里进行说明,也许我会在以后另外写一篇介绍反射的文章。

classtest

{

staticvoidMain(string[]args)

{

System.Reflection.MemberInfoinfo=typeof(MyClass);//通过反射得到MyClass类的信息

//得到施加在MyClass类上的定制Attribute

CodeReviewAttributeatt=

(CodeReviewAttribute)Attribute.GetCustomAttribute(info,typeof(CodeReviewAttribute));

if(att!

=null)

{

Console.WriteLine("代码检查人:

{0}",att.Reviewer);

Console.WriteLine("检查时间:

{0}",att.Date);

Console.WriteLine("注释:

{0}",att.Comment);

}

}

}

在上面这个例子中,Attribute扮演着向一个类添加额外信息的角色,它并不影响MyClass类的行为。

通过这个例子,我们大致可以知道如何写一个自定义的Attribute,以及如何在应用程序使用它。

下一节,我将介绍如何使用Attribute来自动生成ADO.NET的数据访问类的代码。

Attribute在.NET编程中的应用(三)

用于参数的Attribute

在编写多层应用程序的时候,你是否为每次要写大量类似的数据访问代码而感到枯燥无味?

比如我们需要编写调用存储过程的代码,或者编写T_SQL代码,这些代码往往需要传递各种参数,有的参数个数比较多,一不小心还容易写错。

有没有一种一劳永逸的方法?

当然,你可以使用MS的DataAccessApplicationBlock,也可以使用自己编写的Block。

这里向你提供一种另类方法,那就是使用Attribute。

下面的代码是一个调用AddCustomer存储过程的常规方法:

publicintAddCustomer(SqlConnectionconnection,

stringcustomerName,

stringcountry,

stringprovince,

stringcity,

stringaddress,

stringtelephone)

{

SqlCommandcommand=newSqlCommand("AddCustomer",connection);

command.CommandType=CommandType.StoredProcedure;

command.Parameters.Add("@CustomerName",SqlDbType.NVarChar,50).Value=customerName;

command.Parameters.Add("@country",SqlDbType.NVarChar,20).Value=country;

command.Parameters.Add("@Province",SqlDbType.NVarChar,20).Value=province;

command.Parameters.Add("@City",SqlDbType.NVarChar,20).Value=city;

command.Parameters.Add("@Address",SqlDbType.NVarChar,60).Value=address;

command.Parameters.Add("@Telephone",SqlDbType.NvarChar,16).Value=telephone;

command.Parameters.Add("@CustomerId",SqlDbType.Int,4).Direction=ParameterDirection.Output;

connection.Open();

command.ExecuteNonQuery();

connection.Close();

intcustId=(int)command.Parameters["@CustomerId"].Value;

returncustId;

}

上面的代码,创建一个Command实例,然后添加存储过程的参数,然后调用ExecuteMonQuery方法执行数据的插入操作,最后返回CustomerId。

从代码可以看到参数的添加是一种重复单调的工作。

如果一个项目有100多个甚至几百个存储过程,作为开发人员的你会不会要想办法偷懒?

(反正我会的:

-))。

下面开始我们的代码自动生成工程:

我们的目的是根据方法的参数以及方法的名称,自动生成一个Command对象实例,第一步我们要做的就是创建一个SqlParameterAttribute,代码如下:

SqlCommandParameterAttribute.cs

usingSystem;

usingSystem.Data;

usingDebug=System.Diagnostics.Debug;

namespaceDataAccess

{

//SqlParemeterAttribute施加到存储过程参数

[AttributeUsage(AttributeTargets.Parameter)]

publicclassSqlParameterAttribute:

Attribute

{

privatestringname;//参数名称

privateboolparamTypeDefined;//是否参数的类型已经定义

privateSqlDbTypeparamType;//参数类型

privateintsize;//参数尺寸大小

privatebyteprecision;//参数精度

privatebytescale;//参数范围

privatebooldirectionD

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 党团工作 > 入党转正申请

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1