zoukankan      html  css  js  c++  java
  • C#基础-特性(Attribute+AOP)

    序言:

          一个程序员在海滩上发现了一盏神灯。

          他在灯上擦了几下,一个妖怪就从灯里跳出来说:“我是世界上法术最强的妖怪。我可以实现你的任何梦想,但现在,我只能满足

    你一个愿望。”

          程序员摊开了一幅中东地图说:“我想让中东得到永久的和平。”  妖怪答道:“哦,我没办法。自打创世纪以来,那里的战火就没有停息过。这世上几乎没有我办不到的事,但这件事除外。”

          程序员于是说:“好吧,我是一个程序员,我编写的程序有许多用户。你能让他们对我的程序表示满意,并且只提那些可以实现的需求吗?”

          妖怪说:“唔.........,我们还是来看中东地图吧。”

        

    正文:

    注:以上序言与本文毫无关系,请不要多想!

     

    Attribute

     

    第一节:Attribute是什么?

     

    第二节:Attribute怎么用?

     

    第三节:Attribute哪里用?

     

     

         关于Attribute的定义:

     

     

    ²1、.NET大师Jeffrey Richter说:“任何.NET Framework 开发人员都有必要对定制attribute有一个牢靠的掌握”,所以掌握Attribute,这是必须的!

    ²2、对Attribute的定义:  (类似 Java Annotation)
            先来看下微软msdn的定义:
                      Attribute 类将预定义的系统信息或用户定义的自定义信息与目标元素相关联。目标元素可以是程序集、类、构造函 数、委托、枚举、事件、字段、接口、方法、可移植可执行文件模块、参数、属性 (Property)、返回值、结构或其他属性(Attribute)
           通俗的理解:
                     你可以通过Attribute将一些额外信息加在一些目标元素上(类,字段,接口等),程序编译的时候就将这些额外的信息序列化到程序集的元数据中,当你运行程序的时候可以通过反射技术从程序集元数据中读取这些额外信息,并根据这些额外信息决定你程序的某些行为。
     

           说到定义有必要提下Property

             Attribute 和 Property 有什么区别 ?
             因为很多中文把attribute 也翻译为属性,才有了这样的问题,有些人就会混淆,其实 他们是完全不同的东           西,Property就是大家常用的类的属性。所以我建议把 Property 翻译成属性,Attribute不要翻译,也有些书把Attribute 翻译成“特性”。

    不知道乡亲们是怎么理解的,优雅的理解也好,粗俗的理解也罢,只要理解了就好, 关于Attribute的定义我们暂时就提这么多吧,后面再详谈,下面我们直接进入第二节:如何去使用Attribute!

    ²1、先看下.NET Framework预先定义好的一些Attribute 吧:
                      在 .NETFramework 中提供了很多定制好的Attribute供开发人员使用,这些定制的Attribute目的是方便开发者在代码中表达某些意图。下面简单介绍下几个Attribute类都是C#编译器能够理解的特性类:
             
             Obsolete:这个属性用来标记不再使用的程序实体(如类或方法),每次使用标记为过时的实体时,会设定此特性的方法,产生警告或错误。
             Conditional:该特性可以标示出某种环境设置下某个方法是否应该被调用。(定义条件方法)
             Serializable:指示一个类可以序列化。
             DllImport用来标记非.NET的函数,表明该方法在一个外部的DLL中定义.(可以导入其他语言编译的DLL)
             下面我们来写写一些具体的Demo:
             

     

    ²2、看完了系统的我们再来看下我们怎么自己来定义Attribute呢?
              是不是有点忘了?那就再来回顾下Attribute
                     Attribute是指给声明性对象附加一些声明性描述信息,这些信息在经过编译器编译后相当于目标对象的自描述信息被编译进托管模块的元数据中,很显然,如果这些描述信息太多,会大大增加元数据的体积,这一点要注意。编译器只是将这些描述信息编译生成到元数据中,而对Attribute的“逻辑”并不关注。
                     前面提到的特性都是继承于System.Attribute类,CLR要求定制Attribute必须继承于System.Attribute类,为了符合规范,所有的定制特性都要以Attribute后缀,这只是一个规范,也可以不使用此后缀,并没有强制。即使采用了后缀,为了方便编码,C#编译器也是允许在编码时省略后缀的。
                     在特性类名与后缀Attribute间存在一个自动的编译转换。因此当我们用一个特性去修饰一个程序实体时,也可以不给出Attribute这个后缀。编译器首先会在System.Attribute的所有派生类中进行匹配,如果没有找到匹配特性,它就将特性名加上Attribute后缀名后再进行匹配。

     

     

     

    好了,说了这么多,也看了这么多了,开始准备写个自己的Attribute的:

             在写自定义Attribute之前有必要介绍下 AttributeUsage:

             AttributeUsage是另一个预定义的特性类,以帮助我们控制自定义特性的使用。亦即我们可以定义自定义类的特性。这个类描述了如何使用自定义的特性类。AttributeUsage有三个数据特性可用以修饰我们的自定义的特性:

     

     上个最简单的Demo(每个特性意思不再详述,相信大家都明白的):

     

            写了个非常简单的 DemoAttribute ,由于篇幅有限,我们只是简单的列举一些Attribute的应用实例,例子本身不一定合适,一切为了理解,下面第三节我们就来讨论Attribute的意义之所在:

    ²1、软件产品的测试版、体验版、学习版、正式版等不同版本的实现
    ²2ORM的实现
    ²3AOP的实现
    实例一: 
     
     
    实例二:
     

     

    实例三:

    1、先简单介绍下 AOP:
    AOP ->  Aspect Oriented Programming
    常翻译为“面向方面编程”、“面向切面编程”,“切面导向编程”
    通俗理解:一种编程思想,对传统OOP编程的一种补充。
    大师们的普遍理解:
     理解一、它是可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。
          
    理解二、 它是一种行为(Behavior)的注入,在不改变原有逻辑(original logic)的基础上,将一些可重用的其他逻辑 (other logic)注入到原有逻辑(original logic)中。切面(Aspect)即为其他逻辑(other logic),是一些特殊的业务关 注点,包括“事务处理”,“异常捕捉”,“日志记录”,“身份验证”等方面这种“切面”逻辑一般贯彻整个解决方案,AOP方式将这种切面提取出来,实现了降低耦合和代码简洁化。
           
    理解三 、AOP是希望能够将通用需求功能从不相关的类当中分离出来,能够使得很多类共享一个行为,一旦发生变化,不必修改很多类,而只需要修改这个行为即可。
     
    来自维基百科的解释:      
                    Aspect-oriented programming (AOP) is a programming paradigm that increases modularity by enabling improved separation of concerns. This entails breaking down a program into distinct parts (so-called concerns, cohesive areas of functionality). All programming paradigms support some level of grouping and encapsulation of concerns into separate, independent entities by providing abstractions (e.g. procedures, modules, classes, methods) that can be used to implement, abstract and compose these concerns. But some concerns defy these forms of implementation and are called crosscutting concerns because they "cut across" multiple abstractions in a program.

    2、接着我们再简单介绍下为什么使用AOP(直接看Demo):

    很显然,使用AOP模式,代码又回归了干净的业务,只专注于自己的业务,并不管“切面”。

         下面我们上一个简化的Demo来学习下如何实现AOP,其实目前并不需要自己去写AOP框架,我们只需要了解他的原理,目前有很多AOP类库和框架供大家使用,这里只讨论使用 Attribute 来实现AOP,文章最后我给大家上传了一些AOP的实例和框架,有兴趣的家伙可以下载下来详细研究。

            AOP的实现方法,以前用的比较多的是用动态代理来实现, 类似设计模式中的代理模式Proxy,现在建议大家使用优秀的框架实现或类库来实现,我们现在给大家演示的例子就用PostSharp来实现,上代码:

          说明:这个Demo我们还是按照前面“登录”的业务来写,演示我在登录的时候加入“日志记录”的功能,使用AOP模式实现:

     

     

     

     

     

    附录(一些AOP相关的框架):

    1、NFramework

    2、CSharpAOP

    3、EmitAOP

    4、UnityAOP

    5、TinyAOP

    6、PostSharp

    暂时先谈到这里吧,欢迎交流! 

  • 相关阅读:
    GPU编程和流式多处理器(七)
    GPU编程和流式多处理器(六)
    vue——使用vant轮播组件swipe + flex时,文字抖动问题
    golang 修改字符串
    Go 彻底弄懂return和defer的微妙关系
    Redis 的持久化机制
    Redis 缓存击穿
    Redis 缓存穿透
    Redis 雪崩
    正则验证
  • 原文地址:https://www.cnblogs.com/ydchw/p/3458128.html
Copyright © 2011-2022 走看看