C#初探编程
- 1 标识符
- 1.1命名规则
- 1.2标识符命名约定
- 1.2.1 使用有意义的名称
- 1.2.2 避免使用缩写
- 1.2.3. 使用 PascalCase 命名法
- 1.2.4. 使用 camelCase 命名法
- 1.2.5. 使用下划线分隔单词
- 1.2.6. 避免使用关键字
- 2 关键字
- 2.1 关键字详解
- 3 Main方法
- 4 空白
- 5 语句
- 6 控制台输入输出
- 6.1 格式字符串
- 6.2 标准数字格式说明符
- 6.3 注释
HelloWorld程序是一个经典的示例程序,通常用于介绍一门编程语言基本语法及检查开发环境配置是否正确。下面是使用C#语言编写的HelloWorld程序:
using System;
class HelloWorld {
static void Main() {
Console.WriteLine("Hello, World!");
}
}
这个程序的作用是在控制台输出字符串 “Hello, World!”。
现在让我们来逐行解释这个程序:
- 第一行代码
using System;
是引用命名空间 System,它包含了许多常用的类和方法。 - 第三行代码开始定义了一个名为
HelloWorld
的类,它包含一个静态方法Main
。 Main
方法是程序执行的入口点,即从这里开始执行程序。而static
关键字表示该方法是静态的,可以通过类名直接调用,无需实例化该类。Console.WriteLine("Hello, World!");
这行代码输出 “Hello, World!” 字符串到控制台,并自动换行。
当我们运行这个程序时,将会在控制台上看到 “Hello, World!” 这句话。这表明我们已正确配置好开发环境并成功地使用C#语言编写并运行了第一个程序。
从 C# 9 开始,无需在控制台应用程序项目中显式包含 Main 方法。 相反,可以使用顶级语句功能最大程度地减少必须编写的代码。 在这种情况下,编译器将为应用程序生成类和 Main 方法入口点。
下面是一个 Program.cs 文件看,它是 C# 10 中的一个完整 C# 程序:
Console.WriteLine("Hello World!");
借助顶级语句,可以为小实用程序(如 Azure Functions 和 GitHub Actions)编写简单的程序。 它们还使初次接触 C# 的程序员能够更轻松地开始学习和编写代码。
1 标识符
C# 标识符是用来命名变量、方法、类、接口、枚举等程序实体的名称或符号。HelloWorld和Main就是标识符。一个好的标识符应该能够清晰地表达所代表的含义,易于阅读和理解。
1.1命名规则
C# 标识符的命名规则如下:
- 可以由字母、数字和下划线组成。
- 必须以字母或下划线开头。
- 区分大小写。
- 没有长度限制。
1.2标识符命名约定
为了编写易于阅读和理解的代码,我们可以遵循以下命名约定:
1.2.1 使用有意义的名称
标识符的名称应该具有表达力,让人一眼就能看出它代表的含义。例如:
int numRows; // 表示行数量
string name; // 表示名字的字符串
1.2.2 避免使用缩写
尽量避免使用缩写,因为缩写可能会使代码难以理解。如果必须使用缩写,应该使用广为人知的缩写,例如:
int num; // 不好的示例,num 是什么意思不清楚
int numRows; // 好的示例,表示行数量的变量名称更加明确
1.2.3. 使用 PascalCase 命名法
对于方法、类和接口等类型,应该使用 PascalCase 命名法,即每个单词的首字母都要大写。例如:
class HelloWorld {
static void Main() {
//...
}
}
1.2.4. 使用 camelCase 命名法
对于变量、参数和属性等,应该使用 camelCase 命名法,即第一个单词的首字母小写,后面的每个单词的首字母都要大写。例如:
int numRows;
string firstName;
1.2.5. 使用下划线分隔单词
如果需要在标识符中使用多个单词,可以使用下划线将它们分隔开。例如:
private void PanelCanvas_Paint(object sender, PaintEventArgs e) {
// ...
}
1.2.6. 避免使用关键字
C# 语言保留了一些关键字,这些关键字不能用作标识符名称。如果使用关键字作为标识符名称,会导致编译错误。在少数情况下关键字加“@”前缀也可作为标识符,但是强烈反对这样做。“@”只能放在标识符首位。例如,不能使用以下关键字作为标识符名称:
abstract, as, base, bool, break, byte, case, catch, char, ...
定义好的标识符可以使代码更加易于阅读和理解。在编写 C# 程序时,请遵循上述命名规则和命名约定,编写易于理解的代码。
2 关键字
C#关键字是用来帮助编译器解释代码的字符串记号,关键字由小写字母组成。
2.1 关键字详解
- abstract
abstract 关键字用于定义抽象类和抽象方法。抽象类是一种不能实例化的类,只能被子类继承并实现其抽象方法。抽象方法没有具体的实现,必须在子类中进行重写。
- as
as 关键字用于将一个对象转换为指定类型的对象。如果无法进行强制类型转换,则返回 null。
- base
base 关键字用于引用基类实现。它可以用于访问基类的属性、方法和构造函数。
- bool
bool 是布尔值类型,只有 true 和 false 两个取值。
- break
break 关键字用于跳出循环体或 switch 语句。
- byte
byte 是无符号 8 位整数类型,取值范围是 0 到 255。
- case
case 关键字用于选择 switch 语句中的一个分支。
- catch
catch 关键字用于捕获异常并处理。catch 块必须跟随 try 块使用。
- char
char 是 Unicode 字符类型,占用 16 位。
- checked
checked 关键字用于检查算术运算是否发生溢出,如果发生,则会抛出 OverflowException 异常。
- class
class 关键字用于定义一个类,包含成员变量、成员方法和构造函数等。
- const
const 关键字用于定义常量,一旦定义后不可变。
- continue
continue 关键字用于跳过当前循环迭代并执行下一次迭代。
- decimal
decimal 是高精度小数类型,占用 128 位,适合于金融计算等需要高精度的场合。
- default
default 关键字用于 switch 语句中的默认分支。
- delegate
delegate 关键字用于定义委托类型,允许将方法作为参数传递给其他方法,并且可以用于事件处理。
- do
do 关键字用于执行循环体,至少执行一次。
- double
double 是 64 位浮点数类型,比 float 类型精度更高。
- else
else 关键字用于 if 语句的否定分支。
- enum
enum 关键字用于定义枚举类型,列出所有可能的取值。
- event
event 关键字用于定义事件,表示某个操作已经发生或者将要发生。
- explicit
explicit 关键字用于定义显式转换,即将一个类型转换为另一个类型,需要通过强制类型转换实现。
- extern
extern 关键字用于定义外部函数或变量,可以与 DllImport 特性一起使用。
- false
false 表示布尔值 false。
- finally
finally 关键字用于在 try-catch 块结束时执行清理代码,不论是否有异常抛出都会执行。
- fixed
fixed 关键字用于声明一个固定长度的数组,该数组存储在栈上而不是堆上。
- float
float 是 32 位浮点数类型,比 double 类型占用更少的内存,但精度也更低。
- for
for 关键字用于执行循环体。
- foreach
foreach 关键字用于遍历集合元素,语法糖为 foreach (var item in collection) { … }。
- goto
goto 关键字用于跳转到标签,但是常常会导致代码结构混乱,应该避免使用。
- if
if 关键字用于条件语句,根据指定条件的真假执行不同的代码块。
- implicit
implicit 关键字用于定义隐式转换,即将一个类型自动转换为另一个类型,无需进行强制类型转换。
- in
in 关键字用于引用传递参数,在方法中修改参数不会影响原始值。
- int
int 是 32 位有符号整数类型。
- interface
interface 关键字用于定义接口,包含一组方法和属性,不能直接实例化,需要由类来实现。
- internal
internal 关键字用于表示访问权限控制符,表示只能在当前程序集中访问。
- is
is 关键字用于判断对象是否属于指定的类型,返回一个布尔值。
- lock
lock 关键字用于锁定对象,防止多个线程同时访问该对象。
- long
long 是 64 位有符号整数类型。
- namespace
namespace 关键字用于定义命名空间,可以将相关的代码组织在一起。
- new
new 关键字用于创建新的对象实例。
- null
null 表示空引用,即没有指向任何对象。
- object
object 是所有数据类型的基类,可以用于存储任何值。
- operator
operator 关键字用于定义操作符重载,可以重新定义操作符的行为。
- out
out 关键字用于输出传递参数,在方法中修改参数会影响原始值。
- override
override 关键字用于重写基类方法,子类可以对基类的方法进行覆盖实现。
- params
params 关键字用于定义可变长度参数列表,在方法调用时可以传递任意数量的参数。
- private
private 关键字用于表示访问权限控制符,表示只能在当前类中访问。
- protected
protected 关键字用于表示访问权限控制符,表示只能在当前类及其派生类中访问。
- public
public 关键字用于表示访问权限控制符,表示可以在任何地方访问。
- readonly
readonly 关键字用于定义只读字段,一旦初始化后就不能更改。
- ref
ref 关键字用于引用传递参数,在方法中修改参数会影响原始值。
- return
return 关键字用于从函数中返回结果。
- sbyte
sbyte 是 8 位有符号整数类型。
- sealed
sealed 关键字用于防止类被继承,即禁止其他类继承该类。
- short
short 是 16 位有符号整数类型。
- sizeof
sizeof 关键字用于获取类型大小,以字节为单位。
- stackalloc
stackalloc 关键字用于在栈上分配内存,比堆上分配内存更快。
- static
static 关键字用于声明静态成员,静态成员属于类而非对象。
- string
string 是字符串类型,用于存储文本数据。
- struct
struct 关键字用于定义结构体,它是一种值类型,包含一组相关的数据。
- switch
switch 关键字用于多路分支语句,根据指定的表达式执行相应的代码块。
- this
this 关键字用于引用当前对象,可用于访问对象的属性和方法。
- throw
throw 关键字用于抛出异常。
- true
true 表示布尔值 true。
- try
try 关键字用于异常处理块,包含可能抛出异常的代码块,必须与 catch 或 finally 块一起使用。
- typeof
typeof 关键字用于获取类型的 Type 对象。
- uint
uint 是无符号 32 位整数类型。
- ulong
ulong 是无符号 64 位整数类型。
- unchecked
unchecked 关键字用于取消算术运算的溢出检查,即不会抛出 OverflowException 异常。
- unmanaged
unmanaged 指的是非托管代码,即使用原生的 C 或 C++ 等语言编写的代码,这些代码没有被托管代码(由 .NET 运行时管理的代码)所包含。
- unsafe
unsafe 关键字用于标记代码块中包含不安全的代码(比如指针操作),需要启用 /unsafe 编译选项。
- ushort
ushort 是无符号 16 位整数类型。
- using
using 关键字用于自动释放资源,通常用于管理 IDisposable 接口实现的对象。
- virtual
virtual 关键字用于定义虚方法,即可以被派生类重写的方法。
- void
void 是一种返回类型,表示方法不返回任何值。
- volatile
volatile 可以用于修饰字段或变量,以确保其在多线程环境下的可见性和顺序性。
- while
while 是一种循环结构,用于在满足特定条件时重复执行某个代码块。
除了以上的 C# 关键字外,还有一些上下文关键字,它们在特定场合下具有特殊意义,但可以用作变量名。这些上下文关键字包括 add、alias、ascending、async、await、by、descending、dynamic、equals、from、get、global、group、into、join、let、nameof、on、orderby、partial、remove、select、set、value、var、when 和 where。
在使用关键字时应该避免与其它标识符重名,否则会导致编译错误。此外,C# 还支持自定义关键字(使用 #define 指令),但不建议滥用该功能。
3 Main方法
在 C# 中,Main 方法被认为是程序的入口点,程序从Main方法开始执行。对于控制台应用程序,Main 方法是必须的,而对于 Windows 应用程序(如 WinForm 程序),Visual Studio 会自动生成 Main 方法并启动应用程序。
下面是一个简单的控制台应用程序示例,其中包括了 Main 方法:
using System;
class Program
{
static void Main(string[] args)
{
//...
}
}
4 空白
C# 中的空白指的是用于分隔代码中不同部分的空格、制表符和换行符等字符。空白对于代码的可读性和风格有着很大的影响,通常需要遵循一些约定俗成的规范。
以下是一些 C# 空白的使用规范:
- 使用空格来分隔关键字、运算符和其它语法元素,可以使代码更加易读和清晰。
- 在方法和控制结构的左括号之前留一个空格,并在右括号之后也留一个空格。
- 在逗号和冒号之后留一个空格,但不要在分号之后留空格。
- 避免在同一行上使用太多的空白,这会让代码难以阅读。
- 使用代码格式化工具来自动调整代码中的空白,可以提高代码的可读性和一致性。
以下是一个示例代码片段,其中展示了一些 C# 空白的使用:
class Program
{
static void Main(string[] args)
{
Game game = new Game();
game.Start();
}
}
在以上示例代码中程序员可以利用空白对代码进行缩进以增强可读性。
class Program{static void Main(string[] args){Game game = new Game();game.Start();}}
删除一切可以删除的空白版本,对编译器来说和有空白版本并无差别。
5 语句
语句是一条执行某种操作的指令或命令。C# 语句通常以分号结尾(除了特殊情况),它们可以单独成行,也可以组合成块。以下是一些 C# 语句的示例:
- 赋值语句:将一个值赋给变量。
int numRows = 15;
string name = "player 1";
- 控制流语句:让程序按照不同的条件执行不同的操作。
if (i < 10)
{
Console.Write(i + " " + " ");
}
else
{
Console.Write(i + " ");
}
- 调用语句:调用函数或方法执行特定的操作。
Console.WriteLine("无效的位置,请重新输入。");
Game game = new Game();
game.Start();
- 返回语句:从方法中返回一个值。
return false;
以上只是一些常见的 C# 语句示例,C# 还支持很多其它类型的语句,如异常处理语句、循环控制语句等。在编写 C# 程序时,选择合适的语句并正确地使用它们非常重要,能够使程序更加高效、易读和易于维护。
在C#中,块是由0条或多条语句组成的代码段,通常用花括号来将它们括起来。块可以作为一个单独的语句出现,也可以嵌套在其它块中。块的主要用途是控制程序的控制流和作用域。
{
}
if (board.CheckWin(currentPlayer.Piece))
{
Console.WriteLine(currentPlayer.Name + " 获胜!");
gameOver = true;
}
6 控制台输入输出
在 C# 中,控制台输入输出是通过 Console 类来实现的。Console 类提供了很多方法和属性,用于读取用户的输入和向控制台输出信息。
以下是一些常见的控制台输入输出操作示例:
- 向控制台输出文本:使用 Console.WriteLine 或 Console.Write 方法向控制台输出文本。
Console.WriteLine("请输入横坐标:");
Console.Write("平局!");
- 获取用户输入:使用 Console.ReadLine 方法获取用户在控制台上输入的文本。
string name = Console.ReadLine();
- 格式化输出:使用占位符等方式格式化输出内容,可以使输出更易读、更美观。
int x = 15, y = 10;
Console.WriteLine("The value of x is {0} and the value of y is {1}.", x, y);
- 控制台颜色:使用 Console.ForegroundColor 和 Console.BackgroundColor 属性设置控制台输出文本的前景色和背景色。
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("This text will be displayed in red.");
Console.ResetColor(); // 恢复默认颜色
以上只是一些常见的控制台输入输出示例,C# 的 Console 类还支持更多高级的控制台操作,如清除屏幕、光标移动等。在编写控制台应用程序时,正确地使用控制台输入输出是非常重要的,能够帮助我们实现与用户的交互、调试程序等功能。
6.1 格式字符串
下面使用 Console.WriteLine 或 Console.Write 方法向控制台输出文本:
- 使用
Console.WriteLine()
方法:Console.WriteLine()
方法接受一个或一个以上参数,如果超过一个参数,参数之间用逗号分割,并且第一个参数必须是字符串。例如:
int age = 30;
string name = "Kevin";
Console.WriteLine("My name is {0} and I am {1} years old.", name, age);
// 输出:"My name is Kevin and I am 30 years old."
在这个例子中,{0}
和 {1}
是占位符,分别对应后面的 name
和 age
参数。C#可以使用任意顺任意数量的占位符和替换值,而且次数不限。
int age = 30;
string name = "Kevin";
Console.WriteLine("My name is {1} and I am {0} years old. {0} is an integer", age, name);
// 输出:"My name is Kevin and I am 30 years old.30 is an integer"
- C# 6.0引入字符串插值功能。 使用
$"..."
语法:通过在字符串前添加$
符号,可以创建一个带有格式字符串的插值表达式。例如:
int age = 30;
string name = "Kevin";
Console.Write($"My name is {name} and I am {age} years old.");
// 输出:"My name is Kevin and I am 30 years old."
在这个例子中,花括号中的表达式会被求值,并替换为相应的值。可以在表达式前面添加格式说明符来控制输出格式。
- 使用格式化字符串方法:一些类型(如数字和日期)提供了自己的格式化方法。例如:
int age = 30;
DateTime birthday = new DateTime(1990, 6, 18);
Console.Write($"My birthday is {birthday:d} and I am {age} years old.");
// 输出:"My birthday is 6/18/1992 and I am 30 years old."
在这个例子中,d
是日期格式说明符,用于控制输出日期的格式。
Console.WriteLine和Console.Write两个方法的区别是Console.Write方法不在输出文本后自动添加换行符,而是保持当前光标位置在同一行上。
6.2 标准数字格式说明符
以下是 C# 中常见的标准数字格式说明符及其示例:
格式说明符 | 含义 | 示例 |
---|---|---|
C | 货币。使用货币符号进行格式化,并且可以指定小数位数。 | 12345.6789 -> $12,345.68 |
D | 十进制整数。将数字转换为十进制整数形式输出。可以指定最小位数。 | 12345 -> 12345 |
E 或 e | 科学计数法。使用指数形式输出数字,并且可以指定小数位数和指数位数。 | 12345.6789 -> 1.234568E+004 |
F 或 f | 定点数字。使用指定的小数位数输出数字。 | 12345.6789 -> 12345.68 |
G 或 g | 通用数字。根据具体情况,可以使用定点或科学计数法输出数字。 | 12345.6789 -> 12345.6789 ,1234567890123456 -> 1.23456789012346E+015 |
N | 千位分隔符。每隔三位插入一个逗号,并且可以指定小数位数。 | 12345.6789 -> 12,345.68 |
P 或 p | 百分比。将数字乘以 100 并加上 % 符号,并且可以指定小数位数。 | 0.123456 -> 12.35% |
X 或 x | 十六进制整数。将数字转换为十六进制形式输出,可以指定最小位数和大小写形式。 | 255 -> FF |
这些标准数字格式说明符可以与 $"..."
语法或 string.Format()
方法配合使用,例如:
int number = 12345;
double amount = 12345.6789;
Console.WriteLine($"The number is {number:D}, the amount is {amount:C}.");
// 输出:"The number is 12345, the amount is $12,345.68."
string formattedString2 = string.Format("The number is {0:D}, the amount is {1:C}.", number, amount);
// 输出:"The number is 12345, the amount is $12,345.68."
在这个例子中,{number:D}
使用了 D
标准数字格式说明符,表示使用十进制整数格式输出 number
变量的值。{amount:C}
使用了 C
标准数字格式说明符,表示使用货币格式输出 amount
变量的值。
6.3 注释
在 C# 中,注释(Comment)是一种用于在代码中添加说明和备注的机制。C# 提供了三种不同的注释方式:
- 单行注释:使用
//
进行注释,可以在一行代码后面添加注释。例如:
int age = 30; // 定义年龄变量
- 多行注释:使用
/*
和*/
进行注释,可以在多行代码之间添加注释。例如:
/*
这是一个多行注释。
可以在多行之间自由添加文本。
*/
int age = 30;
- 文档注释:使用
///
进行注释,可以为类、方法、属性等成员添加文档注释。例如:
/// <summary>
/// 计算两个数的和。
/// </summary>
/// <param name="a">第一个数。</param>
/// <param name="b">第二个数。</param>
/// <returns>两个数的和。</returns>
public int Add(int a, int b)
{
return a + b;
}
在这个例子中,使用了文档注释来说明 Add()
方法的作用、参数和返回值。可以使用 Visual Studio 的 IntelliSense(智能感知) 功能来查看文档注释。
传统观点:使用注释可以使代码更加清晰易懂,并且有助于他人理解和维护代码。在编写代码时适当添加注释,尤其是对于复杂的代码或不常见的功能,更需要详细的注释说明。
当代思维:编写思路清晰并且易懂的代码比标注繁杂的注释更有价值。