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×10 38
double
System.Double
64
约(±)5.0× 10 -324到 7.9×10×10 28
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);
}
}
 
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值