序号 | 系列文章 |
---|---|
0 | 【C#基础】初识编程语言C# |
前言
:smile:hello大家好,我是writer桑,前面的章节了解了编程语言C#和.NET平台,那么本章就开始学习C#中的程序结构的相关内容,希望看完大家能够有所收获,感谢支持!
程序结构
C# 中的关键组织结构概念包括 程序、 命名空间、 类型、 成员和 程序集。 程序声明类型,而类型则包含成员,并被整理到命名空间中。 类型示例包括 类、结构和接口。 成员示例包括 字段、方法、属性和事件。 编译完的 C# 程序实际上会打包到程序集中。程序集的文件扩展名通常为 .exe 或 .dll,具体视其分别实现的是应用程序还是库而定。
1. 程序实例
接下来我们看一个数据结构堆栈程序的实例,请思考包含以下代码的程序集:
using System; // using 指令的用法
namespace Acme.Collections // namespace 命名空间的用法
{
// Stack栈类的声明
public class Stack<T>
{
Entry _top;
// 推入元素操作
public void Push(T data)
{
_top = new Entry(_top, data);
}
// 删除并抛出元素
public T Pop()
{
if (_top == null)
{
throw new InvalidOperationException(); // 如果栈为空,直接抛出无效操作的异常
}
T result = _top.Data; // 取出顶部的元素赋给result
_top = _top.Next; // 使其指针指向下一个元素
return result;
}
// 嵌套类Entry
class Entry
{
public Entry Next { get; set; }
public T Data { get; set; }
public Entry(Entry next, T data)
{
Next = next;
Data = data;
}
}
}
// 需要被其它文件引用,这里 Main方法加上注释。
/*
public class Program
{
// 程序开始和结束的地方,Main方法
static void Main(string[] args)
{
Stack<int> s = new Stack<int>();
s.Push(1);
s.Push(10); // 堆栈包括1, 10
Console.WriteLine(s.Pop());
Console.WriteLine(s.Pop());
Console.WriteLine(s.Pop()); // InvalidOperationException: 堆栈为空
}
}
*/
}
- 程序的第一行 using System 为 using 指令的用法,即在程序中引用 System 命名空间;一个程序允许有多个 using 关键字的存在,注意在C#程序中 using 指令的用法还有两种,分别是为类型创建别名和释放资源。
- 程序的第三行使用 namespace 关键字创建命名空间,即此程序的命名空间名为 Acme.Collections ;在C#程序中,命名空间在两个方面被大量使用分别为: .NET使用命名空间来组织它的许多类、 控制类和方法名称的范围空间
- 接下来几行即 class 类的声明; 此类的完全限定的名称为Acme.Collections.Stack。 类中包含多个成员:一个 _top 字段、两个方法 Push 和 Pop 和一个 Entry 嵌套类。
- 而 Entry 类还包含三个成员:一个名为 Next 的属性、一个名为 Data 的属性和一个构造函数。Stack 是泛型类。它具有一个类型参数 T,在使用时替换为具体类型。
- 接下来使用 class 关键字声明 Program 类,并且定义了 Main 方法;Main 方法是可执行程序的入口点,也是程序控制开始和结束的位置。其中 Main 方法的参数 string[] args 表示接收控制台命令的参数,不需要时也可不写。
- // 在 C# 程序中表示单行注释,此外还有 /.../ 表示多行注释、XML注释方式 /// 用来解释代码块的具体含义,便于开发者理解。
堆栈的解释:
堆栈是一个“ 先进后出”(FILO) 集合。 添加到堆栈顶部的新元素。 删除元素时,将从堆栈顶部删除该元素。 前面的示例声明定义堆栈的存储和行为的 Stack 类型。 可以声明一个引用 Stack 类型的实例的变量来使用该功能。
2. 程序集
程序集包含中间语言 (IL) 指令形式的可执行代码和元数据形式的符号信息。 执行前,.NET 公共语言运行时的实时 (JIT) 编译器会将程序集中的 IL 代码转换为特定于处理器的代码。
由于程序集是包含代码和元数据的自描述功能单元,因此无需在 C# 中使用 #include 指令和头文件。 只需在编译程序时引用特定的程序集,即可在 C# 程序中使用此程序集中包含的公共类型和成员。 例如,此程序使用 acme.dll 程序集中的 Acme.Collections.Stack 类, 示例代码如下:
using Acme.Collections; // 引用 Acme.Collections 命名空间
class Example
{
public static void Main()
{
var s = new Acme.Collections.Stack<int>(); // 生成一个堆栈s
s.Push(1); // 堆栈包含 1
s.Push(10); // 堆栈 1, 10
s.Push(100); // 堆栈 1, 10, 100
Console.WriteLine(s.Pop()); // 堆栈 1, 10
Console.WriteLine(s.Pop()); // 堆栈 1
Console.WriteLine(s.Pop()); // 堆栈是空的
}
}
- 若要编译此程序,需要引用包含前面示例中定义的堆栈类的程序集。 (using Acme.Collections; )
- C# 程序可以存储在多个源文件中。在编译 C# 程序时,将同时处理所有源文件,并且源文件可以自由地相互引用。从概念上讲,就好像所有源文件在被处理之前都连接到一个大文件。
- 在 C# 中永远都不需要使用前向声明,因为声明顺序无关紧要(极少数例外情况除外)。 C# 并不限制源文件只能声明一种公共类型,也不要求源文件的文件名必须与其中声明的类型相匹配。
3. 顶级语句
顶级语句也即不使用 Main 方法的程序,从 C# 9 开始,无需在控制台应用程序项目中显式包含 Main 方法。 相反,可以使用顶级语句功能 最大程度地减少必须编写的代码。 在这种情况下,编译器将为应用程序生成类和 Main 方法入口点。
也就是从 C# 9 开始,在程序中直接写出以下代码即可运行:
Console.WriteLine("Hello World!");
注意:
- 一个应用程序只能有一个入口点,也就是一个项目只能有一个包含顶级语句的文件。 在项目中的多个文件中放置顶级语句会导致编译器错误:只有一个编译单元可具有顶级语句。
- 可以显式编写 Main 方法,但它不能作为入口点。 编译器将发出以下警告:程序的入口点是全局代码;忽略“Main()”入口点。
结语
:heavy_check_mark: 以上就是C#程序结构的介绍,希望能够对大家有所帮助。请大家多多支持,你们的支持就是笔者创作最大的动力!