Mono 基本概念

类别:.NET开发 点击:0 评论:0 推荐:

 

4

C#基本概念

 

本章内容

ü         基本数据类型

ü         操作符

ü         流程控制

ü         数组

ü         结构、枚举类型和类

ü         委托和事件

本章内容不是全面介绍C#语言,而是对C#语言进行一个总结。假定读者已经对C#语言已经了解,详细的C#资料可参看微软的.NET SDK的文档。

请读者原谅我加上这一章,之所以这样是因为我想对C#语言的一些功能点做一些总结,尽量以图表的方式展示这些功能点。我也买过很多书,java和.net的,很多书的前4、5章的内容基本相同,都是介绍开发语言的。我们读者哪有那么多银子区买这些重复的东西呢?

4.1基本数据类型

C#定义了十三种简单类型,下面的表是对这些类型做了比较。

C#关键字

框架类型

占用字节(位)

范围

sbyte

System.SByte

8

-128到127

byte

System.Byte

8

0到255

short

System.Int16

16

-32768到32767

ushort

System.UInt16

16

0到65535

int

System.Int32

32

-2147483648到2147483647

uint

System.UInt32

32

0到4294967295

long

System.Int64

64

-9223372036854775808到9223372036854775807

ulong

System.UInt64

64

0到18446744073709551615

char

System.Char

32

所有Uniccode字符

float

System.Single

32

约(±)1.5×10-45到7.9×3.4×1038

double

System.Double

64

约(±)5.0×10-324到7.9×10×1028

decimal

System.Decimal

128

8

bool

System.Boolean

1

true 或者false

 

我们通过一个例子来查看各个类型的最大最小值。

Console.WriteLine("SByte:MaxValue=" + SByte.MaxValue + ",MinValue=" + SByte.MinValue);

Console.WriteLine("Byte:MaxValue=" + Byte.MaxValue + ",MinValue=" + Byte.MinValue);

Console.WriteLine("Int16:MaxValue=" + Int16.MaxValue + ",MinValue=" + Int16.MinValue);

Console.WriteLine("UInt16:MaxValue=" + UInt16.MaxValue + ",MinValue=" + UInt16.MinValue);

Console.WriteLine("Int32:MaxValue=" + Int32.MaxValue + ",MinValue=" + Int32.MinValue);

Console.WriteLine("UInt32:MaxValue=" + UInt32.MaxValue + ",MinValue=" + UInt32.MinValue);

Console.WriteLine("Int64:MaxValue=" + Int64.MaxValue + ",MinValue=" + Int64.MinValue);

Console.WriteLine("UInt64:MaxValue=" + UInt64.MaxValue + ",MinValue=" + UInt64.MinValue);

Console.WriteLine("Char:MaxValue=" + Char.MaxValue + ",MinValue=" + Char.MinValue);

Console.WriteLine("Char:MaxValue=" + Char.MaxValue + ",MinValue=" + Char.MinValue;

Console.WriteLine("Single:MaxValue=" + Single.MaxValue + ",MinValue=" + Single.MinValue);

Console.WriteLine("Double:MaxValue=" + Double.MaxValue + ",MinValue=" + Double.MinValue);

Console.WriteLine("Decimal:MaxValue=" + Decimal.MaxValue + ",MinValue=" + Decimal.MinValue);            

Console.WriteLine("Boolean:TruString=" + Boolean.TrueString + ",FalseString=" + Boolean.FalseString);

运行此程序,显示结果如下:

据Mono文档介绍,Char类型的最大值为65535,最小值为0。不过这里显示是乱码。这是因为这两个值的类型都是char。我们可以通过下面的代码片段将其转换成double,终端中将显示最大值65535和最小值0:

double maxValue = Convert.ToInt32(Char.MaxValue);

double maxValue = Convert.ToInt32(Char.MinValue);

Consloe.WriteLine(“Char:MaxValue=” +maxValue + “,MinValue=” + minValue);

 

这13种类型都是值类型,值类型和引用类型的区别在下面介绍。这里如何区分值类型和引用类型呢?

       区分值类型和引用类型是相当重要的,尤其在对方法的参数进行判断的时候很容易出错。值类型都继承于System.ValueType和它的子类,如结构类型和枚举类型。

       考虑下面的一个例子。

using System;

public class ValueandRef

{

         public class Person

         {

                   public string name;

                   public int age;

                   public Person()

                   {

                   }

                   public Person(string p1,int p2)

                   {

                            name=p1;

                            age=p2;

                   }      

         }

         //引用类型

         Person person = new Person("xuwen",32);

         //值类型

         int salary = 12000;

         //打印person和salary的值

         public void PrintInfo()

         {

                   Console.WriteLine(person.name + "'s age:" + person.age);

                   Console.WriteLine(person.name + "'s salary:" + salary);

         }

         //更改数值,p1参数是引用类型,p2参数是值类型

         public void ChangedValue(Person p1,int p2)

         {

         //这里p1设置为新对象,p1的地址不再指向person,而是指向了一个新的Person。

                   p1 = new Person();

                   p1.name ="yuer"; //这里对值的修改只影响新的对象的值,person的值不被修改

                   p1.age = 23;

                   p2 = 5400;//值类型,这里的修改不会影响salary

         }

        

         public void ChangedValueTwo(Person p1,int p2)

         {

                   p1.name = "hutu"; //这里p1和person是同一对象

                   p1.age =27;

                   p2 = 7200; //值对象,这里的修改不会影响salary

         }

         public void Test()

         {

                   Console.WriteLine("PrintInfo:Before the first changed");

                   PrintInfo();

                   Console.WriteLine("PrintInfo:after the first changed");

                   ChangedValue(person,salary);

                   PrintInfo();

                   Console.WriteLine("PrintInfo:after the second changed");

                   ChangedValueTwo(person,salary);

                   PrintInfo();

                  

         }

        

        

         public static void Main(string[] args)

         {

                   ValueandRef vandr = new ValueandRef();

                   vandr.Test();

         }

}

 

编译运行这个程序,显示结果如下:

这里Person是引用类型,int是值类型。

常用转义符号:

转义符号

代表的意思

Unicode值

\’

单引号

\u0027

\”

双引号

\u0022

\\

反斜杠

\u005C

\0

null

\u0000

\a

Alert

\u0007

\b

空格

\u0008

\f

换页

\u000C

\n

新行

\u000A

\r

回车

\u000D

\t

水平tab

\u0009

\v

竖直tab

\u000B

字符串格式化规则:

String.Format和WriteLine使用相同的字符串格式化规则。指定格式的表达式为:

“{N[,M][:FormatString]}”,…,arg0………。

其中N指定要格式化的参数的整型数,从0开始编号。

M是可选的整型数,它指定包含格式化数值的区域的宽度,剩余空间由空格填充。如果M是负数,那么格式化数值被左对齐,否则右对齐。

FormatString是格式化指定符。

arg0…是指要格式化的字符串。

如:Console.WriteLine(“{0:D3}”,834);

标准格式指示符如下:

字符(不区分大小写)

意义

c

货币数值

d

十进制

e

指数

f

固定点

g

常规

n

带千分号的数字,如1,000,000

p

带百分号的数字

r

可恢复

x

十六进制

自定义格式指示符:

格式符

用途

说明

0

显示零占位符

补零

#

显示数字占位符

使用有效数字替换#

.

小数点

.

,

千分符号

如1,000,000

%

百分比表示

显示%

E+0

E-0

e+0

e-0

指数

指数格式化

\

字符字面值

显示格式字符

‘XYZ’

“XYZ”

字符串字面值

显示引号内的字符串

;

节分隔符

 

 

日期类型的格式化符:

格式字符

日期模式

说明

d

MM/dd/yyyy

短日期模式

D

dddd.MMMM dd,yyyy

长日期模式

t

HH:mm

短时间模式

T

HH:mm:ss

长时间模式

f

dddd,MMMM dd,yyyy HH:mm

完整日期/时间模式(短时间)

F

dddd,MMMM dd,yyyy HH:mm:ss

完整日期/时间模式(长时间)

g

MM/dd/yyyy HH:mm

常规日期/时间模式(短时间)

G

MM/dd/yyyy HH:mm:ss

常规日期/时间模式(长时间)

M或m

MMMM dd

月日模式

R或r

ddd,dd MMM yyyy

RFC1123 模式

s

yyyy-MM-dd HH:mm:ss

可排序的日期/时间模式;符合 ISO 8601

u

yyyy-MM-dd HH:mm:ss

通用的可排序日期/时间模式

U

dddd,MMMM dd,yyyy HH:mm:ss

通用的可排序日期/时间模式

Y或y

MMMM,yyyy

年月模式

由于操作系统区域设置的不同分隔符可能不同。

4.2 操作符

C#中的操作符以及操作符优先级

类别

操作符

基本

(x),x.y,f(x),a[x],x++,x--,new,typeof,sizeof,checked,unchecked

一元

+,-,!,~,++x,--x,(T)x

乘除法

*,/,%

加减法

+,-

位操作

<<,>>

关系

<,>,<=,>=,is

相等

= =

逻辑AND

&

逻辑XOR

^

逻辑OR

|

条件AND

&&

条件OR

||

条件

?:

赋值

=,+=,-=,*=,/=,%=,<<=,>>=,&=,^=,|=

一元操作符基本上都是右结合的,二元操作符除赋值操作符外都是左结合的。

自加和自减操作符的前缀形式和后缀形式的执行顺序不同。

前缀形式++x:

1.       将x加1

2.       返回x的值

int count=10;

int result;

result= 10 + (++count); //result=21,count=11

后缀形式x++:

1.       返回x的值

2.       将x加1

int count=10;

int result;

result= 10 + count++; //result=20,count=11

 

4.3 流程控制

4.3.1 if语句

if语句有下列形式

if (条件为真)

         执行相应操作

 

if (条件一为真)

         执行相应操作

else if (条件二为真)

         执行相应操作

else if (条件三为真)

         执行相应操作

else if (条件n为真)

         执行相应操作

[else

         执行相应操作]

这里的条件都是布尔表达式。

布尔表达式的比较操作符为:

操作符

名称

大于

>=

大于或者等于

小于

<=

小于或者等于

= =

恒等于

!=

不等于

布尔表达式的逻辑操作符号为:

逻辑操作符

说明

C#中的表示

AND

短路与

&&

OR

短路或

||

XOR

异或

^

NOT

!

AND

&

OR

|

考虑下面的一段代码:                                          

(x>100) && (y>90)

如果x=10,则布尔表达式不会再进行y>90的判断而直接返回false,这种机制称之为短路。

(x>100) &(y>90)

如果x=10,这时候编译器即使知道了结果返回false,它还是进行y>90的判断。

 

4.3.2 switch语句

switch(switch表达式)

{

         case (常量表达式一):

                   [

                   执行相应操作;

                   break;

]

     case (常量表达式二):

                  [

                   执行相应操作;

                   break;

]

         …

         case (常量表达式N):

                   [

                   执行相应操作;

                   break;

]

         [default:

                   执行相应操作]

}

 

switch有几个原则:

1.       switch表达式必须能够转换成sbyte、byte、short、ushort、int、uint、long、ulong、char、string类型或者再这些类型上的一个枚举。

2.       一个switch部分可以包括0到多个执行相应操作的语句。只有包括0个语句(也就是不写相应操作)才允许穿越。

3.       如果包括多个语句,必须加跳转语句,如break,goto(或许在C#2.0中goto语句要被禁用了)。

 

4.3.3 while循环

do

{

         执行相应操作  //第一次必然执行,以后只要表达式为真就继续执行

}while(布尔表达式)

 

while(布尔表达式)   //只要条件为真就继续执行

{

         执行相应操作;

}

 

在循环体内可以加入continue或者break跳转语句。continue将中止循环体内后面的语句,执行下一次判断,而break将中止循环,跳出循环,转到循环外的下一条语句。

 

4.3.4 for循环

for ([初始化语句],[循环条件],[更新变量])

{

         执行相应操作;

}

初始化语句中可以使用逗号,来初始化多个变量如int i=0,int j=0。

初始化语句、循环语句、更新变量语句都可以是空语句。

for( ;  ; )

{

         ..;

}

循环体内可以使用continue、break跳转意义,功能和while语句相同。

 

4.3.5 foreach语句

foreach(变量 in 集合)

{

         …

}

循环体内可以使用continue、break跳转意义,功能和while语句相同。

4.4 数组

数组的声明如下

类型[] 一维数组变量名;

 

类型[ , , , …, ] 多维数组变量名;

 

类型[][][]…[] 锯齿数组变量名;

 

数组的初始化。

int[] numbers = {1,34,3,23,223};

 

int[] numbers = new int[5];

 

int[,] numbers = {{41,22,3},{12,36,23}};

 

int[,] numbers = new int[2,3];

 

int[][] numbers = new int[3][];

numbers[0] = new string[3];

numbers[1] = new string[7];

numbers[2] = new string[6]

 

4.5 结构、枚举类型和类

4.5.1 结构

结构的声明如下:

[属性][访问修饰符] struct  <结构名>[:接口]

{

         [结构体]

}[;]

访问修饰符可以是public、private、protected、internal、protected internal。

下面定义了一种结构:

struct Student

{

         public Student(string name,int score)

         {

                   Name=name;

                   Score=score;

         }

         public string Name;

         public int Score;

}

 

结构的成员可以是构造器、常量、字段、方法、特性、索引器、操作符以及嵌套的类型。但是请注意,结构不能创建无参数的构造器。

结构是值类型的。

4.5.2 枚举

枚举的声明如下:

[访问修饰符] enum 枚举类型名称 [:N类型]

{

         枚举成员 [=N类型的值];

枚举成员 [=N类型的值];

}

N类型可以是byte、sbyte、short、ushort、int、uint、long、ulong类型。

枚举类型是值类型的。

4.5.3 类

类的定义如下:

[属性] [访问修饰符] class 类名 [:基类[,接口]]

{

         [类成员]

}[;]

类的成员有以下类型:

1.       字段 字段是用于保存值的成员变量

2.       方法 方法是进行业务处理的代码

3.       特性 一种访问类内部字段的方法,对于客户来说好像直接访问字段一样。

4.       常量

5.       索引器 这种成员可以操作逻辑上包含数据数组的类,就好像这个类是数据一样。提供了一种简便访问类内部数组的一种方法。(意义大吗?)

6.       事件 用于触发事件

7.       操作符 类可以重载操作符。

8.       构造函数和析构函数

访问修饰符

public     可以在类定义和派生类之外访问

private    只能在类定义内部访问

protected  只能由类定义和派生类访问

internal   智能在当前编译单元内可以访问,根据代码的位置而不是类层次结构决定可见性

类的更多信息请参看微软的.NET SDK文档。

在这里不想再多介绍,因为这类的书籍在书店比比皆是,而且内容基本相同,如果列在这里,既有抄袭的嫌疑,还有读者需要掏出更多的money来购买此书。再重申一篇,之所以增加本章,主要是对C#的一些特点进行总结,以便编程的时候能有所帮助。

类的静态变量、只读成员、常量成员、构造函数、修构函数、特性、索引器、操作符重载、类的继承、虚方法、方法覆盖、静态构造器等每个专题都可以深入探讨,但本书编写的目的不在于此,希望读者多这些功能点能有深入的了解。比如虚方法,为什么要声明虚方法、虚方法常用在哪些设计模式中。

 

4.6 委托和事件

委托的声明方式如下:

[访问修饰符] delegate <返回类型> 委托名称 ([参数列表]);

组播委托的声明如下:

[访问修饰符] delegate void 委托名称 ([参数列表]);

组播委托可是使用+、+=、-、-=操作符。

 

一个事件有对象发出一个信号,并讲这些信号通知给已经注册的其他对象。c#中的事件是一个特殊化处理的组播委托。

将大象装进冰箱需要几步?三步。为类增加事件处理需要几步?五步,正确。当然有时候可能步数还少。

1.       定义一个事件参数,这个参数保存了事件的相关信息。

如LifeEventArgs,这个类继承System.EventArgs类,可以加入保存事件的相关信息的字段和方法。

public class LifeEventArgs : System.EventArgs

{

        public readonly string AboutYou;

        public LifeEventArgs(string about)

        {

               AboutYou = about;

        }

}

2.       定义一个委托原型,用于指定事件触发时被调用的方法的原型。

public delegate void LifeEventHander(Object sender,LifeEventArgs);

3.       定义一个事件成员

public event LifeEventHander Life;

4.       定义一个虚方法,负责通知事件的注册对象

protected virtual void OnLife(LifeEventArgs e)

{

     if (Life != null)

{

            Life(this,e);

}

}

5.       定义一个方法,用来触发事件

public void PerformLifeArgs(int age)

{

      

       if (age == 30)

       {

              LifeEventArgs e = new LifeEventArgs(“三十而立,你立了吗?”);

              OnLife(e);

}

}

 

 

本文地址:http://com.8s8s.com/it/it42798.htm