知识大全 C#特性学习与使用

Posted

篇首语:只要自己上进,不怕人家看轻。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 C#特性学习与使用相关的知识,希望对你有一定的参考价值。

C#特性学习与使用  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  C#特性以前的时候 用过C#中的特性 但只是会用 什么原理 有什么用这些问题不清楚 今天就腾出时间 学习了一下

  C#中的特性使用Attribute描述 在使用时 就像是java中的批注一样 不过C#使用中括号 特性用来描述我们的数据 编译器能够识别这些特性 以附加信息的形式存放在生成的元数据中 供clr使用

  下边看一个简单的应用view plainprint?

  static void Main(string[] args)

   DisplayRunningMsg() DisplayDebugMsg() Trace( 方法执行到结尾了!! ) Console Read()

   [DllImport( User dll )] public static extern int MessageBox(int hParent string msg string Caption int type) [Conditional( DEBUG )] private  static  void DisplayRunningMsg()

   Console WriteLine( This is debug ) Console WriteLine( 开始运行Main子程序 当前时间是 +DateTime Now)

  [Conditional( DEBUG )] [Obsolete] private  static  void DisplayDebugMsg()

   Console WriteLine( 该方法已经废弃啦!!! )

  DllImport特新允许我们引入一个外部的dll 下边做一个函数的声明 我们就可以调用了

  Conditional属性表示在该种条件下就执行下边的代码 所以[Conditional( DEBUG )]此种标识的方法就只有在调试的时候才会在执行    [Obsolete]特性标记该方法已经废弃

  运行上述代码输出(在debug模式下)

   

  看的出来程序执行了[Conditional( DEBUG )]标记的方法 如果我们debug改为release 那么再次执行

   

  程序并没有执行上述方法 看的出来 由于特性[Conditional( DEBUG )]标记 是的在release模式下 代码并没有运行其标记的函数 那么 我们就可以利用这个做一个error trace 使其只在debug的模式下输出当前错误信息 包括行号 方法名 位置等 这里要用到 stacktrace类

  Ok 说到这里 你应该对特性有了以最最基本的了解

  那么 究竟什么是特性呢?

  其实特性也是一个类 比如[Conditional( DEBUG )] 就是构造了以Conditional对象(调用构造方法public Conditional(string type) 对 DllImport( User dll )对应的也有一个类DllImport 下边我们自定义一个特性 你就会明白很多

  首先需要定一个一个类 该类需要集成Attribute 使其成为一个特性……NET约定特性类都已Attribute结尾 然后在该类中定义一下字段和属性 完成构造

  代码如下view plainprint?

  [AttributeUsage(AttributeTargets All AllowMultiple = true Inherited = true)] class TrackerAttribute Attribute

  private string opUsername private string opName private DateTime dateTime private string note

  public  TrackerAttribute(string  opUsername string  opName string date)

   this opUsername = opUsername this opName = opName this dateTime = DateTime Parse(date)

  //位置参数 通过构造函数传递值public string  OpUsername get return opUsername

  public  string  OpName get return opName

  public  DateTime DateTime get return dateTime

  //命名参数 提供set public string  Note get return note set note = value

  public override string ToString()

   return 操作人 + opUsername + 操作名 + opName + 时间 + dateTime + 备注 + note

  嗯 对 他和普通的类几乎没什么差别 只不过继承于Attribute 然后他本身又有一些特性 我们做逐一介绍我们在类TrackerAttribute 定义了几个字段 完成了构造函数TrackerAttribute(string opUsername string  opName stringdate)

  那么我么在使用的时候就需要写[Tracker( opusername opname note= 这是备注 )] 嗯 是的 使用类型(参数值 参数值)的方法完成了该对象的构造 即调用了该类的构造函数 构造函数里与字段对应的参数叫做位置参数 因为写的时候必须位置一一与源构造函数相同 其他不通过构造函数传入参数传递的 叫做命名参数 使用字段名=字段值 的形式赋值 这样完成函数构造和一些属性的赋值 一般情况下 我们将位置参数提供get访问 而命名参数则提供get和set 因为位置参数已经能够同感哦构造函数访问赋值了

  这个特性类上边还有几个特性 AttributeTargets表示当前特性的作用范围 他是一个位标记的枚举 比如all field method 标记过后 智能在相应的地方做该特性书写 比如指定枚举是作用与字段 那么如果该特性写在类上边 就会报错

  如上 你的特性类就完成了

  这样你就可以在其他方法上做该特性的标记了

  我们定义了特性 最重要的还是要获得该特性中的值 下边是获得的方法view plainprint?

  Type type = typeof(Program) object[] objects = type GetCustomAttributes(false) foreach (var o in objects)

   TrackerAttribute trackerAttribute = o as TrackerAttribute if (trackerAttribute != null)

  Console WriteLine(trackerAttribute ToString()) else Console WriteLine( 获得对象为空 )

  type GetCustomAttributes(false) 该方法将会获得该类上的所有特性标记 返回的是一个object的数组 你可以遍历 然后转换为你的指定特性 访问相应字段即可 同样 你也可以通过type getMethods()[ ] 获得一个methodinfo对象 然后调用该methodinfo对象的GetCustomAttributes方法即可

  介绍了如上的这些 我们利用特性 实现为枚举增加一个获得其描述的功能

  例如定义枚举MyEnummyenum=MyEnum TypeA 调用myenum ToDescription 可以得到字符串 类型A 我们可以想到定一个描述特性 然后在各个枚举元素上 做该特性的标记 然后提供扩展方法 访问该特性 取得该特性值

  代码如下枚举定义view plainprint?

  public enum MyType [Description( A类型 )] TypeA [Description( B类型 )] TypeB [Description( C类型 )] TypeC

  特性类DescriptionAttribute定义如下view plainprint?

  [AttributeUsage(AttributeTargets Field AllowMultiple =true Inherited = true)] class DescriptionAttribute Attribute private string description public  string Description get return description

  public  DescriptionAttribute(String description)

   this description = description

  指定该特性只用于字段 定义DescriptionAttribute(String description)构造函数

  Ok 现在还缺少枚举的ToDescription方法 C#中的枚举是不支持定义方法的

  我们可以为其做一个扩展方法扩展方法需要一个静态类 参数前要加this 同时也指定了被扩展的对象 调用时可使用扩展对像的实例调用 也可以使用该静态类来调用 详细内容可参考

  扩展类如下view plainprint?

  public  static class Extension

  public  static string ToDescription(this MyType myEnum)

   Type type = typeof (MyType) FieldInfo info= type GetField(myEnum ToString()) DescriptionAttribute descriptionAttribute= info GetCustomAttributes(typeof (DescriptionAttribute) true)[ ] as DescriptionAttribute if (descriptionAttribute != null)

  return descriptionAttribute Description else return type ToString()

  这样MyType就多了一个ToDescription的方法 返回的值就是对应的特性值

  在main方法中MyTypemyType = MyType TypeB Console WriteLine(myType ToDescription()) 控制台输出 B类型 达到了我们想要的效果

  这个方法还是很有用的

cha138/Article/program/ASP/201311/21770

相关参考

知识大全 了解C#特性匿名类型与隐式类型局部变量

了解C#特性匿名类型与隐式类型局部变量  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! &

知识大全 c#学习体会:使用 ref 和 out 传递数组

  c#学习体会:使用ref和out传递数组(downmoon)希望与大家分享与所有的out参数一样在使用数组类型的out参数前必须先为其赋值即必须由接受方为其赋值例如public stat

知识大全 C#语言学习:C#数据报编程之测试程序

C#语言学习:C#数据报编程之测试程序  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  C#中自定

知识大全 C#反射方法学习总结

C#反射方法学习总结  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  摘要本文介绍今天把C#反射方

知识大全 C#学习笔记(一)

C#学习笔记(一)  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  finalize方法:终结器 

知识大全 C# 学习使用ErrorProvider

C#学习使用ErrorProvider  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! &

知识大全 C#中if语句基础学习

C#中if语句基础学习  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  usingSystem;c

知识大全 实战开发C# 索引器学习笔记

实战开发C#索引器学习笔记  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  简单说来所谓索引器就是

知识大全 C# 索引器实战开发学习笔记

C#索引器实战开发学习笔记  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  这是使用C#开发智能手

知识大全 学习c#中Shear的使用方法

学习c#中Shear的使用方法  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!通过代码来学习一起看下