热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

CLR类型设计之方法与构造器

无论学习那门语言都要学习函数体,C#,JAVA,PHP,都会涉及到函数体,而C#的函数体成员并不少,方法和构造器就是函数体成员之一,函数体成员还包括但不限于:方法,属性,构造器

 

           无论学习那门语言都要学习函数体,C#,JAVA,PHP,都会涉及到函数体,而C#的函数体成员并不少,方法和构造器就是函数体成员之一,函数体成员还包括但不限于:方法,属性,构造器,终结器,运算符及索引器。

            方法就是某个类相关的函数,也可以返回简单的基元类型或者什么也不反回,方法可以定义其公开性,如果使用static修饰符则变为静态方法。

            属性是可以从客户端访问到的函数组,访问形式和访问类相同,C#为读写类中的属性提供了专用语法。

            构造器是实例化对象时自动调用的特殊函数,必须与所属的类同名,且不能有返回类型,构造器用于初始化字段的值,可通过不同参数进行重载。

            终结器类似与构造函数,但是CLR检测到不再需要某个对象时调用他,他的名称与类相同,但前面有一个~符号 

            运算符执行的最简单操作就是“+’“-’“*’“/’这些基本运算,C#也支持重载运算符

             索引器允许对象以数组的或集合的方式进行索引。

             构造器

              以上就是函数体的基本成员和方法的基本定义,接下来我们先说一下构造器,为什么说构造器?

              因为构造器实际上会帮我们很好的理解方法一个类的初始化过程,我们会发现无论是一个对象实体或是方法,大部分都会放在cs文件中,而构造器是初始化对象的,我建立了一个Student的类里面只有一个字段一个函数体,在Main函数中我初始化了Student类,运行就会发现构造器函数以及执行,并且调用了方法write

             可以发现,当创建一个类型的实例时:

             1)为实例的字段分配内存。

             2)初始化对象的附加字段(类型对象指针和同步块索引)。

             3)调用类型的实例构造器来设置对象的初始状态。

运行后输出的结果    

               实例构造器永远不能被继承。

               因为实例构造器不能被继承,类只有类自己定义的实例构造器,所以就不能用virtual,new,override,sealed,abstract修饰符来定义构造器。 类型构造器可以用于接口(C#不允许这样做),引用类型,值类型。实例构造器用来设置一个类型某个实例的初始化状态,类型构造器用来设置一个类型的初始化状态。默认情况下,如果定义的类没有显式的定义一个构造器,编译器会默认的定义一个无参的构造器。在默认构造器的实现中,它只是简单的调用了基类的无参构造器。

              当我们在值类型里面定义了一个类型构造器时,CLR不一定会调用这个静态构造器,例子创建的是无参类构造器,会在第一次初始化时创建,所以我们再次实例化stu的时候,控制台会输出“我是函数方法1”,如果一个类构造器的方法里,引入了其他类型定义了类型构造器,JIT会检测是否已经在AppDomain里面执行过。如果没有执行,则发起对类型构造器的调用,否则不调用。

                 当程序运行后,线程会开始执行并最终获取调用构造器的代码。实际上有可能会是多个线程执行同一个方法,CLR想要确保一个类型构造器在一个AppDomain里面只执行一次,当一个类型构造器被调用时,调用的线程会获取一个互斥的线程同步锁,这时如果有其他的线程在调用,则会阻塞。当第一个线程执行完后离开,其他的线程被唤醒并发现构造器的代码执行过了,所以不会继续去执行了,从构造器方法返回。CLR通过这种方式来确保构造器仅仅被执行一次。

             提示:

             由于CLR会确保类型构造器在每一个AppDomain里面只会执行一次,是线程安全的。所以如果要初始化任何单例对象(singleton object),放在类型构造器里面是再合适不过了。

      静态构造器

      静态构造函数是实现对一个类进行初始化的方法成员. 它一般用于对静态数据的初始化. 静态构造函数不能有参数,不能有修饰符而且不能被调用,当类被加载时,类的静态构造函数自动被调用.

    在一个程序的执行过程中,静态构造器最多只执行一次.

    静态构造器在类的静态成员初始化之后执行.或者说编译器会将静态成员初始化语句转换成赋值语句放在静态构造器执行的最开始.

    静态构造器在任何类的静态成员被引用之前执行. 

    静态构造器在任何类的实例变量被分配之前执行.

           

    类型构造器性能

                  调用类型构造器并不那么简单,JIT编译器不得不决定是否生成调用它的代码,并且CLR要确保调用是线程安全的。当编译器决定发起一个调用来执行类型构造器,它必须判断是否应该这样做,有两种可能性:

                   1.JIT在创建类型的第一个实例的代码之前立即发起或者在访问类的非继承的字段,成员的代码之前立即调用

                    2.JIT在首次访问一个静态字段,静态方法,实例方法,或调用一个实例构造器的代码之前某个时间调用,因为CLR要确保静态构造器在其他成员被访问之前运行。

                  构造函数中,还有一个特殊的存在,  readonly关键字是一个可在字段上使用的修饰符。 当字段声明包括 readonly 修饰符时,该声明引入的字段赋值只能作为声明的一部分出现,或者出现在同一类的构造函数中。

   可以说readonly一般只在构造器初始化的时候赋值,其余的时候不能改变他的值。

         扩展方法

              c# 扩展方法出来已久,介绍扩展方法的文章也很多,简单点说就是可以在不改变现有类的情况下给这个类添加方法。我觉得扩展方法的最大意义在于我们可以给那些我们根本无法修改的类,比如String,添加我们自定义的方法。既然无法通过修改来添加,那就只能通过扩展了。在使用扩展方法时,可以像调用实例方法那样调用静态方法。这就很大程度的方便了代码的开发。

                

       扩展方法的基本原则:

       (1).C#只支持扩展方法,不支持扩展属性、扩展事件、扩展操作符等。

      (2).扩展方法(第一个参数前面是this的方法)必须在非泛型的静态类中声明,扩展方法必须有一个参数,而且只有第一个参数使用this标记。

      (3).C#编译器查找静态类中的扩展方法时,要求这些静态类本身必须具有文件作用域。

      (4).C#编译要求“导入”扩展方法。(静态方法可以任意命名,C#编译器在寻找方法时,需要花费时间进行查找,需要检查文件作用域中的所有的静态类,并扫描它们的所有静态方法来查找一个匹配)

      (5).多个静态类可以定义相同的扩展方法。

      (6).用一个扩展方法扩展一个类型时,同时也扩展了派生类型。 

        扩展方法不易乱用,尤其是在基类中扩展,其所有派生类都会有这个方法,很容易造成不应该出现的地方出现,另外扩展方法必须为顶级类,不能在嵌套类中使用扩展方法。扩展方法可以扩展很多种类型,包括但不限于,扩展委托,枚举,接口。

         由于扩展方法可以在很多.netformwork提供的类库上使用扩展方法,例如:Enumerable,Queryable,String等等,也可以用于扩展异常方法,扩展枚举。本文篇幅有限,所以我们举其中一个示例。我们写一个如下的String扩展类,string是c#里面最最常用的类,和它的使用频度比起来,它的操作确少的可怜,实例方法只有三十个左右,静态方法只有十多个,
                  首先我们把string类最常用的静态方法IsNullOrEmpty扩展成“实例”方法:

                  只需要建立一个新的静态类,然后写一个方法名,将需要扩展的类参数前加上this就可以了。

                 

             在调用的时候,就可以直接把静态方法IsNullOrEmpty扩展成“实例”方法来调用。是不是就方便了很多,这只是一个抛砖引玉的例子。

           

            在这里推荐一篇博文,博文里讲了很多具体的方法实例。

            http://www.cnblogs.com/ldp615/archive/2009/08/07/1541404.html

 

        

 

          

           

 

 

 

 

          


推荐阅读
  • Final关键字的含义及用法详解
    本文详细介绍了Java中final关键字的含义和用法。final关键字可以修饰非抽象类、非抽象类成员方法和变量。final类不能被继承,final类中的方法默认是final的。final方法不能被子类的方法覆盖,但可以被继承。final成员变量表示常量,只能被赋值一次,赋值后值不再改变。文章还讨论了final类和final方法的应用场景,以及使用final方法的两个原因:锁定方法防止修改和提高执行效率。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • C语言注释工具及快捷键,删除C语言注释工具的实现思路
    本文介绍了C语言中注释的两种方式以及注释的作用,提供了删除C语言注释的工具实现思路,并分享了C语言中注释的快捷键操作方法。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 猜字母游戏
    猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 原文地址:https:www.cnblogs.combaoyipSpringBoot_YML.html1.在springboot中,有两种配置文件,一种 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • Android JSON基础,音视频开发进阶指南目录
    Array里面的对象数据是有序的,json字符串最外层是方括号的,方括号:[]解析jsonArray代码try{json字符串最外层是 ... [详细]
author-avatar
蔡心怡湖人永蓉
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有