业务应该这么写--特性

Posted gdouzz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了业务应该这么写--特性相关的知识,希望对你有一定的参考价值。

       特性真的好常见,用到地方也挺多的。

       在我平时工作中,看得比较多的特性有Web端:权限控制Authorize,过滤器,序列化,WCF,Webservice里面也有很多,WebMethod,DataContract,还有做桌面端的用得最多的DllImport(可以直接和Win32程序进行通信),还有我们常用到ORM,特性真的是无所不能,好像高逼格的地方,特性总是要来搞事。下面让我们一起来看看特性究竟是怎么样进行工作的。

   (一)特性出现的背景和初衷是什么,用来解决什么问题

           特性:给类,方法等提供附加的功能,增强了软件系统的灵活性,促进了功能的松散耦合。

           用特性呢,可以避免多个类似的代码段,创建更为可读和清晰的代码。如果我们可以用.Net自带的特性,我们应该积极的用。

   如果不能的话呢,我们就可以自己定义一个特性类。特性属于声明式编程的一种。

   (二)特性的好处和坏处,带来的挑战是什么

          特性的好处:在不破坏类型封装的前提下,增加一点额外的信息和功能。更加灵活了。就是可以把业务和非业务逻辑区分得更开。

          特性的坏处:定义。应用和反射特性能带来许多便利。所以很多开发人员都喜欢用这些技术。而特性是存在元数据里面的,可能会对性能有一些影响。因为要用反射的话,内部都必须扫描托管模块的元数据,执行字符串比较来定位到指定的特性类。这样操作是会耗费一定时间的。

假如对性能要求比较高的话,可以缓存这些结果。

 (三)适用场景  

          1、业务场景

         我们平时很多公共逻辑,比如需要登录才可以进行授权。定义枚举的时候,要带上描述信息。ORM里面的表名,列名映射关系。等等,还有很多地方,欢迎大家补充。

   (四)特性的组成部分和关键点

           4/1 特性的基本组成

           技术分享图片

           从上图可以知道,特性是属于元数据里面的内容的,我们也可以通过反编译来看看一下就可以明白了。

           1、如下例子:

  class Program
    {
        [Text()]
        static void Main(string[] args)
        {
            Console.WriteLine("test");
        }
    }

    public class TextAttribute : Attribute
    {
        
    }

        我们直接来看反编译这段程序之后的IL;

        技术分享图片

           从上面可以看出,特性就是存在我们元数据中的,而且还会去调用这个特性类的构造函数。

           4/2 特性的基础知识点

           1、特性类,都必须要继承自Attribute。这是因为面向CLR的所有编译器都必须识别Attribute,并且最终能在元数据中生成特性信息。

           编译器有点傻的就是不管这个特性有没有用,都会生成对应的元数据。

            2、特性可以应用于程序集,模块,类型,字段,返回值,方法,参数,属性,事件。

            3、接下来我们思考一个问题,我们是不是定义一个特性,然后就可以随便用呢,用在属性,方法,程序集,等等这些属性上。假如我们不指定特性的使用范围呢,那我们反射的时候,是不是要从方法,属性,类上面都检测一下是否含有这个特性呢,想想这样会给我们性能带来多大的影响呢。所以C#的设计者给我们提供了一个 [AttributeUsage(AttributeTargets.All,AllowMultiple =true,Inherited =true)] 这个东西。

               (1)AttributeUsage是一个特性类,可以通过reflector看看它里面就明白了

                 技术分享图片

     我们直接需要传三个参数的构造函数。 [AttributeUsage(AttributeTargets.All,AllowMultiple =true)]

             AttributeTargets 这是一个枚举。这个主要是用来指定特性的作用范围。作为一个程序员,我们应该要根据需要来合理指定。

             技术分享图片

             Inherited: 这个是说这个特性是否要进行继承,如果要设置为true的话呢,我们反射去检查它的派生类是否应用了这个特性。

              一般情况下,我们不会把这个值设置为true,这样除了会额外的检查,可能还会带来混淆。所以一般建议定义特性类的时候,把它

             设定为sealed,减少混淆,避免这次检查。

             AllowMultiple:一般来说,太多特性多次应用于同一个目标是没有意义的。没有什么特别必要把这个值设置为true。

           4/3 特性的三部曲。

          1、定义一个类,继承自Attribute类,并且类名是以Attribute结尾的。

          2、给指定的方法,属性,类等等,给需要用特性的地方,加上特性打上标记。 

          3、通过反射来调用,使得特性生效。

          很多人的错觉,就是以为写上特性就可以生效。所有让特性生效的地方一定是主动应用了这个特性。

    (五)特性的底层原理和关键实现

          定制特性能有效,完全是因为元数据和反射这个东东。

    (六)已有的实现和它进行对比

         之前我们没用特性的时候,我们普通的做法就是,假设现在是做Webservice开发,定义一个父类(Base),里面写一些通用的方法,然后所有的asmx都继承这个父类,之后在每个需要用的地方调用一下。

         估计还有其他做法,我之后再慢慢分享,今天实在是太累了...欢迎大家留言讨论,祝大家中秋快乐。

以上是关于业务应该这么写--特性的主要内容,如果未能解决你的问题,请参考以下文章

别再这么写代码了,这几个方法不香吗?

如何写好业务代码

假如计算机是中国人发明的,那代码应该这么写

花2个小时考C认证,这不比埋头写这么多代码强?

为啥程序员都应该用 Markdown?怎么用才更高效

Controller层代码这么写,简洁又优雅!