C#基础
namespace aa
{
class MyFirstClass
{
static void Main()
{
Console.WriteLine("This isn't at all like Java!");
Console.ReadLine();
return;
}
}
}
说明:
(1) 每个语句必须用一个分号(;)结尾
(2) 语句可以写在多个代码行上,不需要使用续行字符
(3) 单行注释以“//”开头,多行注释/* …*/
(4) 跟Java一样,所有的C#代码都必须包含在一个类中
(5) 每个C#可执行文件都必须有一个入口点——Main()方法,该方法要么返回void,要么返回一个整数(int)
2. 变量
2.1 变量的定义
在c#中声明变量使用下述语法:datatype identifier;
例如: int i;
无论变量的数据类型是什么,声明变量的c#语法都是相同的。
多个变量的声明,如果类型相同,可以用一个语句声明,如果类型不同,必须用多个语句声明:
例如:int x=10,y=20;// x and y are both ints
int x = 10, bool y = true;// this won’t compile!
2.2 变量的初始化
C#编译器需要对变量初始化之后才能在操作中引用该变量,C#编译器把未初始化的变量当作错误来看 待,这样可以防止我们无意中从其它程序遗留下来的内存中获取垃圾值。
在C#中实例化一个引用对象需要使用new关键字。
objSomething = new Something(); // this creates a Something on the heap
2.3 变量的作用域
一般情况下,确定作用域有以下规则:
1) 只要字段所属的类在某个作用域内,其字段也在该作用域内。
2) 局部变量存在于表示声明该变量的块语句或方法结束的封闭花括号之前的作用域
3) 在for、while或类似语句中声明的局部变量存在于该循环体内。
4) 同名的局部变量不能在同一作用域内声明两次。
{
int j = 20;
for(int i=0;i<10;i++)
{
int j=30;//Can't do this -j is still in scope
Console.WriteLine(j+i);
}
}
5) 编译器可以区分字段和方法中的局部变量。
namespace aa
{
class ScopeTest2
{
static int j = 20;
public static void Main()
{
int j = 30;
Console.WriteLine(j);
return;
{
}
}
3. 常量
常量格式:const int a = 10;
在C#中,只能把局部变量和字段声明为常量。
说明:
1) 常量必须在声明时初始化,且不能更改
2) 常量的值必须在编译时用于计算。因此不能从一个变量中提取值来初始化常量。如果需要这么做,应使用只读字段
3) 常量总是静态的
4) 常量在程序中至少有3个好处:a)使程序更易于阅读 b)使程序更易于修改 c)更容易避免程序出现错误
4. 预定义数据类型
C#把数据类型分为两种:值类型和引用类型。
值类型直接存储其值,数据存储在堆栈中;引用类型存储对值的引用,而数据存储在托管堆上。
C#有15个预定义类型,其中13个是值类型,2个是引用类型(string和object)。
13个值类型包括8个整数类型sbyte、short、int、long、byte、ushort、uint、ulong;2个浮点类型float、double;1个deciaml类型decimal;1个bool类型bool;一个字符类型char;
1) 如果代码没有对某个非整数值硬编码,则编译器一般假定该变量是double。如果想指定值为float,可以在其后加上字符f(或F) float f =
2) decimal类型不是基本类型,所以在计算时使用该类型会有性能损失,要把数字指定为decimal,可以在数字后面加上字符m(或M) decimal d =
3) bool值不能和整数值转换,bool值必须是true或者false。
4) C#中,可以在字符串前面加上字符@,那么字符串中的所有字符都看作是其原来的意思。
string filepath = @”C:\ProCSharp\First.cs”;
5. 流控制
1)条件语句(if语句、switch语句)
a)if子句中的表达式必须等于布尔值,当“==”误写成“=”时,会导致一个编译错误。
b)case的值必须是常量表达式——不允许使用变量,且常量不能相同(字符串可以作为测试变量)。
如果一个case子句为空,就可以从这个case跳到下一个case上,这样就可以用相同的方式处理两个或多个case子句。
在C#中,switch子句里面case子句的排放顺序是无关紧要的。
2)循环
C#除了for循环、while循环和do…while循环 以外增加了foreach循环。foreach循环可以迭代集合中的每个项目,但不能改变集合中各项的值。 如果需要改变各项的值,就应使用for循环。例如:
{
Console.WriteLine(temp);
}
3)跳转语句(goto、break、continue、return)
goto跳转到程序中用标签指定的另一行:
Console.WriteLine(“this won’t be executed”);
Label1:
Console.WriteLine(“Continuing execution from here”);
goto语句有两个限制:不能跳转到像for循环这样的代码块中,也不能跳出类的范围,不能退出try…catch块后面的finally块。
break可以用于退出for、foreach、while、或do…while循环。
continue只从循环的当前迭代中退出,然后在循环的下一次迭代开始重新执行,而不是退出循环。
return用于退出类的方法,把控制返回方法的调用者。
6. 枚举
枚举是用户定义的整数类型,在声明一个枚举时,要指定该枚举可以包含的一组可接受的实例值。
{
Morning,Afternoon,Eveing
}
7. 数组
定义:int[] integers;
初始化:integers = new int[32];
所有的数组都是引用类型,并遵循引用的语义
8. 命名空间
命名空间提供了一种组织相关类和其它类型的方式,它时一种逻辑组合,而不是物理组合。
{
using System;
public struct Subscriber
{
}
}
命名空间可以嵌套,注意不允许在另一个嵌套的命名空间中声明多部分的命名空间。
为了避免命名空间输入的繁琐,可以用using语句来解决。
using System;
using Wrox.ProCSharp;
命名空间也可以用别名来代替:using alias = NamespaceName;
9. Main()方法
C#程序是从Main()方法开始执行的,该方法必须是类或者结构的静态方法,且返回类型必须是int或void。
如果程序包含多个Main()方法,编译器就会返回一个错误,但是可以使用/main选项,显示的告诉编译器把哪个方法作为程序的入口点:
例如:csc MainExample.cs/main:Wrox.ProCSharp.Basics.MathExample
也可以为Main()方法传送参数:
public static int
{
}
编译好之后,可以在执行文件名后面加上参数:
ArgsExample /a /b /c
10. 控制台I/O
Console.ReadLine()从控制台读取一行文本
Console.Write()将指定的值写入控制台窗口
Console.WriteLine()输出的结果最后添加一个换行符
格式化显示:
Console.WriteLine(“{0} plus {1} equals {2}”, i,j,i+j);
也可以指定宽度,{n,w} n是参数索引,w是宽度值,正值表示右对齐,负值表示左对齐
还可以使用格式字符串:
Console.WriteLine(“{0,9:c2}”,i);
最后,可以使用占位符来代替这些格式字符串:
double d = 0.234;
Console.WriteLine(“{0:#.00}”,d)
结果为:0.23
11. XML文档说明
///<summary>
/// The Add method allows us to add two integers
///</summary>
///<returns>Result of the addition(int)</returns>
///<param name=”x”>First number to add</param>
///<param name=”y”>Second number to add</param>
编译:csc /doc:Math.xml Math.cs
12. C#预处理指令
预处理指令不会转化为可执行代码中的命令,但会影响编译过程的各个方面。例如:可以使用预处理指令禁止编译程序编译代码的某一部分。
1)#define和#undef
#define DEBUG 告诉编译器存在给定名称的符号
#undef DEBUG 删除符号的定义
必须把#define和#undef放在C#源代码的开头,在声明要编译的任何对象的代码之前。
#define本身没有什么用,必须跟其它预处理指令结合使用。
2)#if,#elif,#else,#endif
这些指令告诉编译器是否要编译某个代码块
{
#if DEBUG
Console.WriteLint(“x is ” + x);//这行代码只有在定义了DEBUG后才会执行
#endif
}
#elif(=else if)和#else 指令都可以用在#if块中,也可以嵌套#if块
3)#warning 和#error
当编译器遇到它们时,会分别产生一个警告或者错误。如果遇到#warning,会给用户显示#warning指令后面的文本,之后编译器继续进行。如果遇到#error,会给用户显示#error后面的文本,作为一个编译错误信息,然后会立即退出编译,不会生成IL代码。
4)#region和#endregion
用于把一段代码标记为给定名称的一个块,使代码布局清晰明了
5)#line
用于改变编译器在警告和错误信息中显示的文件名和行号信息。这个指令用得不多。