1、第一个C#程序
1.1 代码:
namespace ConsoleApplication1//名称空间
{
class Program//类
{
static void Main(string[] args)//可执行文件的入口函数
{
Console.WriteLine("Hello Word!");//输出
Console.ReadLine();//读入
return;//退出
}
}
}
1.2 编译并运行(我在VS13中进行编译运行的),结果如图
1.3 详细介绍
(1)大多数语句都以分号(;)结尾
(2)用花括号({ })把语句组合成块
(3)单行注释以//开头,多行注释以(/*)开头,以(*/)结尾
2. 变量
(1)声明变量:datatype identifier;
2.1 变量的初始化
(1)C#有两个方法可确保变量在使用前进行了初始化:变量是类或结构中的字段,如果没有显式初始化,创建这些变量时,其默认值就是0;方法的局部变量必须在代码中显式初始化,之后才能在语句中佼用它们的值。此时,初始化不是在声明该变量时进行的,但编译器会通过方法检查所有可能的路径,如果检测到局部变量在初始化之前就使用了它的值,就会产生错误。
(2)在C#中实例化一个引用对象需要使用New关键字。Something Objsomething = new Something();
2.2 类型推断
(1)类型推断(Type inference)使用var关键字。编译器可以根据变量的初始化值推断变量的类型。
(2)例:
namespace study2_2_2
{
class Program
{
static void Main(string[] args)
{
//定义3个类型推断的变量
var name = "Bugs Bunny";
var age = 25;
var isRabbit = true;
//获取上述3个变量的类型
Type nameType = name.GetType();
Type ageType = age.GetType();
Type isRabbitType = isRabbit.GetType();
Console.WriteLine("name's type is :" + nameType.ToString());
Console.WriteLine("age's type is :" + ageType.ToString());
Console.WriteLine("isRabbit's type is :" + isRabbitType.ToString());
}
}
}
(3)输出:
(4)遵循规则:
- 变量必须初始化,否则,编译器就没有推断变量类型的依据
- 初始化器不能为空。
- 初始化器必须放在表达式中。
- 不能把初始化器设置为一个对象,除非在初始化器中创建了一个新对象。
2.3 变量的作用域
(1)变量的作用域是可以访问该变量的代码区域
(2)确定作用域遵循以下规则:只要类在某个作用域内,其字段(也称为成员变量)也在该作用域内。
- 局部变量存在于表示声明该变量的块语句或方法结束的右花括号之前的作用域内。
- 在for、while或类似语句中声明的局部变量存在于该循环体内。
2.3.1 局部变量的作用域冲突
(1)同名的局部变量不能在同一作用域内声明两次
(2)代码:
namespace study2_3_1
{
class Program
{
static int Main(string[] args)
{
for(int i=0;i<10;i++)//for循环
{
Console.WriteLine(i);
}
for (int i = 9; i >= 0; i--)
{
Console.WriteLine(i);
}
return 0;
}
}
}
(3)结果:
两次声明都是在循环内部声明的。
2.3.2 字段和局部变量的作用域冲突
(1)C#把在类级别声明的变量看做字段,把方法中声明的变量看做局部变量。
(2)代码:
namespace study2_3_2{
class Program
{
static int j = 20;
static void Main(string[] args)
{
int j = 30;
Console.WriteLine(j);
Console.WriteLine(Program.j);//访问类级变量
return;
}
}
}
(3)结果
Main()方法中的变量J隐藏了同名的类级变量,可以使用Object.fieldname访问外部的引用类或结构字段。
2.4 常量:值在使用过程中不会发生变化的变量,在前加上关键字const。
(1)常量特点:
- 常量必须在声明时初始化。指定了其值后,就不能再改写了。
- 常量的值必须能在编译时用于计算。
- 常量总是静态的。
(2)常量的好处:
- 由于使用易于读取的名称(名称的值易于理解)替代了较难读取的数字或字符串,常量使程序
变得更易于阅读。 - 常量使程序更易于修改。
- 常量更容易避免程序出现错误。
3. 预定义数据类型
3.1 值类型和引用类型
(1)区别:值类型直接存储其值,而引用类型存储对值的引用。这两种类型存储在内存的不同地方:值类型存储在堆栈中,而引用类型存储在托管堆上。
(2)代码:
namespace study2_3_11
{
public class Vector //结构
{
public int Value;
}
class Program
{
static void Main(string[] args)
{
Vector x, y;
x = new Vector();
x.Value = 30;
y = x;
Console.WriteLine(y.Value);
y.Value = 50;
Console.WriteLine(x.Value);
}
}
}
(3)
执行这段代码后,只有一个Vector对象,x、y都指向包含该对象的内存位置。要创建对象,必须使用关键字new。所以,对x的修改会影响y,反之一样。
(4)一般把基本类型(如int和bool)规定为值类型,而把包含许多字段的较大类型(通常在有类的情况下)规定为引用类型
3.2 CTS
(1)C#认可的基本预定义类型并没有内置于C#语言中,而是内置于.NET Framework中。例如,在C#中声明一个int类型的数据时,声明的实际上是.NET结构System.Int32的一个实例。
(2)应强调的是,在这种便利语法的背后,类型实际上仍存储为基本类型。
3.3 预定义的值类型:.内置的CTS值类型表示基本类型,如整型和浮点类型、字符类型和布尔类型。
3.3.1 整型
(1)C#支持8个预定义整数类型。
(2)在C#中,所有的数据类型都以与平台无关的方式定义,以备将来C#和.NET迁移到其他平台上。
3.3.2 浮点型:
(1)
3.3.3 decimal类型
(1)
(2)CTS和C#一个重要的优点是提供了一种专用类型进行财务计算,这就是decimal类型,使用decimal类型提供的28位的方式取决于用户.
3.3.4 bool 类型
3.3.5 字符类型
3.4 预定义的引用类型
(1)
3.4.1 Object类型
(1)许多编程语言和类结构都提供了根类型,层次结构中的其他对象都从它派生而来。
(2)两个目的:可以使用Object引用绑定任何子类型的对象;object 类型执行许多一般用途的基本方法.
3.4.2 String类型
(1)string是一个引用类型。String对象被分配在堆上,而不是栈上。因此,当把一个字符串变量赋予另一个字符串时,会得到对内存中同一个字符串的两个引用。但是,string与引用类型在常见的操作上有一些区别。例如,字符串是不可改变的。修改其中一个字符串,就会创建一个全新的String对象,而另一个字符串不发生任何变化。
(2)代码:
namespace study2_3_4_2
{
class Program
{
static void Main(string[] args)
{
string s1 = "a string";
string s2 = s1;
Console.WriteLine("s1 is " + s1);
Console.WriteLine("s2 is " + s2);
s1 = "another string";
Console.WriteLine("s1 is " + s1);
Console.WriteLine("s2 is " + s2);
}
}
}
(3)结果
4. 流控制
4.1 条件语句
4.1.1 if语句:if...else...
4.1.2 switch 语句:switch...case...
4.2 循环
4.2.1 for循环
4.2.2 while循环
4.2.3 do...while...循环
4.2.4 foreach 循环
4.3 跳转语句
4.3.1 goto语句
4.3.2 break 语句
4.3.3 continue 语句:开始执行下一次的迭代,并不退出循环。
4.3.4 return 语句
5. 枚举:枚举是用户定义的整数类型。
(1)优势:枚举可以使代码更易于维护,有助于确保给变量指定合法的、期望的值;枚举使代码更清晰,允许用描述性的名称表示整数值,而不是用含义模糊、变化多端的数
来表示;枚举也使代码更易于键入。
(2)代码:
namespace study2_5_1
{
public enum TimeOfDay //引用
{
Morning = 0,
Afternoon = 1,
Evening = 2
}
class Program
{
static void Main(string[] args)
{
WriteGreeting(TimeOfDay.Afternoon);
}
static void WriteGreeting(TimeOfDay timeofday)
{
switch (timeofday)
{
case TimeOfDay.Morning:
Console.WriteLine("Good morning!");
break;
case TimeOfDay.Afternoon:
Console.WriteLine("Good Afternoon!");
break;
case TimeOfDay.Evening:
Console.WriteLine("Good Evening!");
break;
default:
Console.WriteLine("hello");
break;
}
}
}
}
(3)结果:
(4)在C#中,枚举的真正强大之处是它们在后台会实例化为派生于基类System.Enum的结构。这表示可以对它们调用方法,执行有用的任务。
6. 名称空间:提供了一种组织相关类和其他类型的方式。
(1)与文件或组件不同,名称空间是一种逻辑组合,而不是物理组合。
(2)注意不允许在另一个嵌套的名称空间中声明多部分的名称空间。
(3)名称空间与程序集无关。同一个程序集中可以有不同的名称空间,也可以在不同的程序集中定义同一个名称空间中的类型。
6.1 using语句:要在文件的顶部列出类的名称空间,前面加上using关键字。
6.2 名称空间的别名:using 别名=空间名;
(1)代码:
using System;
using Introduction = study2_6_2;
class Test
{
static void Main(string[] args)
{
Introduction::Program nsex = new Introduction.Program();
Console.WriteLine(nsex.GetNamespace());
}
}
namespace study2_6_2
{
class Program
{
public string GetNamespace()
{
return this.GetType().Namespace;
}
}
}
(2)结果:
7. Main()方法
(1)C#是从方法Main()开始执行的。这个方法必须是类或结构的静态方法,并且其返回类型必须是int或void。
7.1 多个Main()方法
(1)一般会返回一个错误信息,不过可以使用/main选项,后面紧跟Main()方法所属类的全名。
7.2 给Main()方法传递参数:String[ ] args。
8 有关编译C#文件的更多内容
9. 控制台I/O
(1)Console.Write()方法将指定的值写入控制台窗口;Console.WriteLine()方法类似,但在输出结果的最后添加一个换行符。
(2)Console.ReadLine()等。
10. 使用注释
10.1 源文件中的内部注释://、/**/
10.2 XML文档
注释有3中:单行注释、多行注释、文档注释
11. C#预处理器指令
11.1 #define和#undef:定义与删除
11.2 #if、#elif、#else和#endif:条件编译
11.3 #warning和#error
11.4 #region和#endregion:把代码标记为一个块
11.5 #line 用于改变编译器在警告和错误信息中显示的文件名和行号信息。
11.6 #pragma
12. C#编程规则
(1)关键字
(2)Pascal大小写:首字母大写;camel大小写:首字母小写