C#常量和字段以及各种方法的语法总结

时间:2023-01-06 20:12:31

目录

一、 常量和字段.... 1

1、 常量.... 1

2、字段.... 1

二、方法.... 2

1、实例构造器和类(引用类型).... 2

2、实例构造器和结构(值类型).... 2

3、类型构造器.... 3

4、操作符重载方法.... 3

5、转换操作符方法.... 3

6、扩展方法.... 4

三、参数.... 5

1、可选参数和命名参数... 5

2、以引用的方式向方法传递参数.... 5

3、向方法传递可变数量的参数... 6

4、参数和返回类型的设计规范... 6

一、常量和字段

1、 常量

常量使用const标记,表示值恒定不变的符号。可以用c#内置的基元类型和引用为null的引用类型赋值。

优点:

  1. 编译的时候就确定,所以运行很快,编译器在检测到const标识的时候就使用计算好的值代替,生成元数据,在运行的时候Jit二次编译的时候会从元数据中找到值,嵌在机器码里面。所以值类型不会在运行时,加载程序集和动态分配内存。不存在引用。

缺点:

  1. 正是因为以上的优点,所以值类型在处理不同程集的时候,会存在版本控制的问题,因为改了值类型的值以后,另外一个程序集,不会再运行时重新编译的。

2、字段

1、类型字段,实例字段,只读字段(static,默认,readOnly)

类型字段在类型对象中分配内存,类型对象是类型加载到AppDoMain时候创建的,什么时候类型加载到AppDoMain? 通常是引用了该类型的任何方法首次进行Jit编译的时候。

2、字段的内联初始化只是语法上的简化(上图),C#编译器还是会把他们在构造函数中初始化。

3、引用类型的readOnly字段不能变的是引用的地址,而不是引用变量对象的值。

二、方法

  1、实例构造器和类(引用类型)

创建引用类型的实例,首先分派类型字段内存,然后初始化对象的附加字段(类型对象指针和同步块索引),最后调用类型对象的实例构造器(初始化字段,调用基类的构造函数,执行自己的代码)。

  A、 C#会默认生成类型的无参数构造函数,如果手动写了有参数的构造器,则不会生成。即使类的修饰符是abstract,也会生成默认的protected的无参数构造函数(当然可以手动指定public),如果是静态类,C#编译器根本不会再类中生成默认的无参数构造函数,在访问从基类继承来的任何字段之前,必须先调用基类的构造函数,如果没有显示调用,C#编译器也会生成代码自动调用基类的无参数构造函数,最终System.Object的构造函数会被调用。

  2、实例构造器和结构(值类型)

  Clr总是允许创建值类型的实例,并且没有办法阻止值类型实例化,所以值类型需要也不会定义无参数构造函数。如果一个值类型在引用类型里面作为变量使用,处于性能考虑,C#不会为每个执行类性显示调用其构造函数,但是会在使用前初始化值类型。

如果指定了构造函数那必须为所有的字段初始化,否则会报错。

3、类型构造器

  1、类型构造器用于初始化类型的状态,类型默认没有定义类型构造器,如果定义的话也只能定义一个无参数的。

对类型构造器的调用总是由Clr亲自调用的,所以类型构造器访问修饰符是private但是不能手动指定,c#编译器默认加上。

适用于引用类型和值类型(永远别在值类型中定义类型构造器)

  2、调用过程

类型构造器的调用比较麻烦,JIT在编译一个方法的时候,会检查方法中的所有引用,如果有的类定义了类型构造器,Jit就会在appDoMain中检查,是否已经调用过类型构造器,调用过了就不在调用。

  Internal sealed class SomeRefType

  {

  Static SomeRefType()

    {

    }

  }

4、 如果类型构造器抛出未处理的,Clr会认为类型不可用。视图访问该类型的任何字段或者方法都会抛出System.InitializationException。

4、  操作符重载方法

Clr要求操作符重载必须是Public static 只少有一个参数类型是方法的定义类型,编译器会生成一个op_*的方法,该方法有个specialname标志,C#编译器看到源码中+操作符的时候,会检查操作数的类型是否定义了名为op_addition的specialname,而且方法的参数是否兼容操作数的类型,如果存在就生成方法调用,否则就报错。

Public static Int32 operator +(ClassName c1,ClassName c2)

{

}

5、转换操作符方法

Public static implicit operator Int32(Person person)

{

Return 10;

}

6、扩展方法

它允许定义一个静态方法,并用实例方法的语法来调用。

扩展方法必须在非泛型的静态类中声名。

C#编译器在静态类中查找扩展方法时,必须在文件作用域,而不是嵌套类。

使用扩展方法发扩展一个类型同时也扩展了派生类型。所以不要在System.Object上扩展。

扩展方法实际上是静态方法,所以不会Clr对调用者进行null值检查。(下面的代码可以正常运行,但是有可能在方法的内部抛出null异常)

Public static class StringBuilderExtensions

{

Public static Int32 IndexOf(this StringBuilder sb,Char value)

{

For(Int32 i=0,i<sb.Length;i++)

{

If(sb[i]==value)return I;

Return -1;

  }

}

}

编译器找扩展方法的顺序:

首先StringBuilder类或者它的基类是否提供了参数类型为Char 名称为IndexOf的方法,如果有就生成IL代码来调用。如果没有找到匹配的实例方法,就继续检查是否有任何静态类定义了IndexOf的静态方法,方法的第一个参数的类型和当前的调用类型一致且使用this修饰。

为接口提供扩展

Public static class IEnumerableExtensions

{

Public static void ShowItem<T>(this IEnumerable collection)

{

Foreach(var item in collection)

{

Console.WriteLine(item);

}

}

}

为委托定义扩展

Public static class ActionExtentsions

{

Public static void InvokeAndCatch(this Action<Object> ac,Object o)

{

Ac(o);

  }

}

Action<Object> action=o=>Console.WriteLine(o.GetType());

Action.InokeAndCatch(null);

使用委托来引用对象上的扩展方法:

Action a=”Wupo”.ShowItems;

a.InVoke();

调用委托实例 翻译成 唤出比较合适invoke

调用对象方法,叫调用 call

Invoke 是需要唤出某个东西来帮你调用一个信息不明确的方法时,

Call 是知道了方法的名称 参数类型 返回值 等。

三、参数

1、可选参数和命名参数

设计方法的参数,可为部分参数分配默认值,然后调用这些方法的代码可以选择不提供部分参数,使用其默认值。

默认值在参数列表的右边,可选参数,在最后且不能有默认值。

默认值可以是 基元类型,枚举,为null的引用类型。

如果参数使用ref 、out标识就不能设置默认值。

2、以引用的方式向方法传递参数

Clr默认所用的参数都是传值。传递引用类型的时候,对象的引用(对象指针)被传递给方法,指针本身是传值的。对于值类型,传递给方法的是实例的一个副本。调用者本身不收影响。

Clr允许以传引用的方式传递参数,使用out ref关键字,告诉C#编译器生成元数据来指明参数是传引用的,编译器将生成代码来传递参数的地址。

Clr本身不区分out 和ref,生成的IL代码也差不多,只有一个bit标准符不同个,用以表明方法指定的是out还是ref.不同之处是这个标志符绝定了由哪个方法负责初始化引用的对象。 如果方法使用out 来标记 则表明不指望(但是可以)调用者在调用之前就初始化,被调用的方法不能读取参数的值,而且在放回之前必须向这个值写入。相反如果方法使用ref来标记,调用者必须在调用方法之前就必须把参数初始换,被调用的方法可以读取和写入值。

Clr允许根据使用out ref对方法进行重载。

但是不允许仅在out 和ref个有不同的方法进行重载。

对于以引用方式传递给方法的变量,它的类型必须与方法签名中声名的类型相同,否则无法编译,可以使用泛型解决这个问题。

3、向方法传递可变数量的参数

可变参数只能放在方法签名的最后。

Static Int32 Add(params Int32[] values)

{

}

由于有params关键字,所以编译器向参数应用定制特性System.ParamArrayAttribute,C#编译器检测到方法调用,会先检查具有指定名称,同时参数没有应用ParamArrayAttribute特性的方法,找到就生成调用代码。没有找到就会检查使用了ParamArrayAttribute的方法,找到以后编译器先生成代码来构造一个数组,填充它的元素,在生成代码来调用它。

4、参数和返回类型的设计规范

声名参数的类型是,应尽量指定最弱类型,宁愿要接口也不要基类。

IEnumerable<T> 比List<T>好,如果方法需要列表,使用Ilist<T> 也比List<T>好。

C#常量和字段以及各种方法的语法总结的更多相关文章

  1. &lbrack;一&rsqb;class 文件浅析 &period;class文件格式详解 字段方法属性常量池字段 class文件属性表 数据类型 数据结构

    前言概述  本文旨在讲解class文件的整体结构信息,阅读本文后应该可以完整的了解class文件的格式以及各个部分的逻辑组成含义   class文件包含了java虚拟机指令集 和  符号表   以及若 ...

  2. 常量,字段,构造方法 调试 ms 源代码 一个C&num;二维码图片识别的Demo 近期ASP&period;NET问题汇总及对应的解决办法 c&num; chart控件柱状图,改变柱子宽度 使用C&num;创建Windows服务 C&num;服务端判断客户端socket是否已断开的方法 线程 线程池 Task &period;NET 单元测试的利剑——模拟框架Moq

    常量,字段,构造方法   常量 1.什么是常量 ​ 常量是值从不变化的符号,在编译之前值就必须确定.编译后,常量值会保存到程序集元数据中.所以,常量必须是编译器识别的基元类型的常量,如:Boolean ...

  3. C&num;中全局作用域的常量、字段、属性、方法的定义与使用

    场景 在开发中,经常会有一些全局作用域的常量.字段.属性.方法等. 需要将这些设置为全局作用域保存且其实例唯一. 注: 博客主页: https://blog.csdn.net/badao_liuman ...

  4. &period;NET面试题解析&lpar;05&rpar;-常量、字段、属性、特性与委托

      系列文章目录地址: .NET面试题解析(00)-开篇来谈谈面试 & 系列文章索引 弱小和无知不是生存的障碍,傲慢才是!——<三体> 常见面试题目: 1. const和reado ...

  5. CLR via C&num;深解笔记三 - 基元类型、引用类型和值类型 &vert; 类型和成员基础 &vert; 常量和字段

    编程语言的基元类型   某些数据类型如此常用,以至于许多编译器允许代码以简化的语法来操纵它们. System.Int32 a = new System.Int32();  // a = 0 a = 1 ...

  6. &lbrack;CLR via C&num;&rsqb;7&period; 常量和字段

    原文:[CLR via C#]7. 常量和字段 7.1 常量 常量(constant)是一个特殊的值,它是一个从不变化的值. 在定义常量时,它的值必须在编译时确定.确定之后,编译器将常量的值保存到程序 ...

  7. C&num;基础之类型和成员基础以及常量、字段、属性

    首先吐糟一下今天杭州的天气,真是太热了!虽然没有妹子跟我约会,但宅在方寸大的窝里,也是烦躁不已! 接上一篇<C#基础之基本类型> 类型和成员基础 在C#中,一个类型内部可以定义多种成员:常 ...

  8. C&num;学习笔记——常量、字段以及事件

    一 常量与字段 (一) 常量 常量总是被视为静态成员,而不是实例成员.定义常量将导致创建元数据.代码引用一个常量时,编译器会在定义常量的程序集的元数据中查找该符号,提取常量的值,并将值嵌入IL中.由于 ...

  9. python&lowbar;way day18 html-day4, Django路由,(正则匹配页码,包含自开发分页功能), 模板, Model&lpar;jDango-ORM&rpar; &colon; SQLite,数据库时间字段插入的方法

    python_way day18 html-day4 1.Django-路由系统   - 自开发分页功能 2.模板语言:之母板的使用 3.SQLite:model(jDango-ORM) 数据库时间字 ...

随机推荐

  1. MVC 学习系列-Controller

    MVC最核心的也就是Controller了,控制器(controller)在功能中起到了核心功能. 1,)在MVC类库中,根据URL,通过MVCHandler进入MVC处理系统中, 2,)解析初始化对 ...

  2. 初始jQuery

    JQuery是继prototype之后又一个优秀的Javascript库.它是轻量级的js库 ,它兼容CSS3,还兼容各种浏览器(IE 6.0+, FF1.5+, Safari 2.0+, Opera ...

  3. 武汉科技大学ACM :1010&colon; 零起点学算法103——一只小蜜蜂&period;&period;&period;

    Problem Description 有一只经过训练的蜜蜂只能爬向右侧相邻的蜂房,不能反向爬行.请编程计算蜜蜂从蜂房a爬到蜂房b的可能路线数. 其中,蜂房的结构如下所示. Input 输入数据的第一 ...

  4. top 查看资源使用

    top:动态观察程序的变化 ? [root@linux ~]# top [-d] | top [-bnp] 参数: -d :后面可以接秒数,就是整个程序画面更新的秒数.预设是 5 秒: -b :以批次 ...

  5. assert &lpar;boxes&lbrack;&colon;&comma; 2&rsqb; &gt&semi;&equals; boxes&lbrack;&colon;&comma; 0&rsqb;&rpar;&period;all&lpar;&rpar;报错

    根据报错信息,打印以下内容: 代码如下: for i in xrange(num_images): #print ('in append_flipped==================',self ...

  6. Qt中关于QMouseEventbuttons&lpar;&rpar;和QMouseEventbutton&lpar;&rpar;的使用注意

    在进行QT程序开发中经常需要响应鼠标事件,在QWidget或QMainWindow的子类中可以重载如下鼠标事件实现自己需要的效果. virtual void mouseDoubleClickEvent ...

  7. Synchronzied与ReentrantLock

  8. dependency的scope

    scope作用域,一共有三种作用域:compile(编译).runtime(运行).test(测试) 备注:打包必经compile阶段 1.test        测试 2.compile  编译 打 ...

  9. C&num;程序设计入门经典之C&num;的基本语法

    C#代码的外观和操作方式与C++和Java非常类似.初看起来,其语法可能比较混乱,不像书面英语和其他语言.但是,在C#编程中,使用的样式是比较清晰的,不用花太多的力气就可以编写出可读性很强的代码. 与 ...

  10. Form表单提交,js验证

    Form表单提交,js验证 1,  Onclick() 2, Onsubmit() Button标签 input (属性 submit  button )标签 Input type=button    ...