语法概述

这篇笔记我们介绍C#语言的基本语法,我们从一个简单的Hello World程序开始逐步介绍代码的每个部分。由于C#语法大部分和Java非常类似,因此本章节会着重介绍C#和Java间有区别的部分,因此学习本章节前有一定的Java基础是最好的。

Hello World

下面代码是一个最简单的Hello World程序,代码编译执行后会在控制台上输出一行"Hello, world!字符串。

using System;

namespace Gacfox.Demo.DemoNetCore
{
    class Program
    {
        static void Main()
        {
            Console.WriteLine("Hello, world!");
        }
    }
}

第一行使用了using语句,后面的System是一个命名空间,这条语句告知编译器程序使用System命名空间,因为在随后的代码中我们用到了System.Console这个类。namespace语句声明了我们自己代码所使用的命名空间为Gacfox.Demo.DemoNetCore。随后我们定义了一个名为Program的类,并定义了Main()方法,也是C#中的入口方法。方法内部,我们调用了Console类的WriteLine方法,输出了一行文本。

使用顶级语句

C#9引入了顶级语句的写法,我们可以不再编写Main方法和其外层的类了。

Program.cs

using System;

Console.WriteLine("Hello, world!");

代码中,我们的Program.cs文件仅仅包含一条代码,而没有编写任何的Main方法。

但我们要注意,使用顶级语句有一些限制:

  1. 一个应用程序只能有一个入口点,因此也只能有一个代码文件包含顶级语句,否则编译时会报错。
  2. 顶级语句隐式位于全局命名空间中。
  3. 顶级语句可以引用args变量读取命令行参数,类似Main方法的string[] args参数。
  4. 顶级语句中可以直接使用await关键字调用异步方法。
  5. 顶级语句中可以直接return进程的退出代码,和Main方法相同。

代码规范

从上面例子程序中,我们可以看出C#语言代码规范上和Java的一些差异。

首先,C#提倡对于局部变量和私有成员变量使用lowerCamelCase,其余(包括公开的成员变量、方法名、类名、命名空间)使用PascalCase,这和Java不同。注意C#中的入口方法Main也是PascalCase的,如果你错写成了lowerCamelCase是无法编译通过的,报错原因是找不到可执行程序的入口方法。

另外,C#建议代码的左大括号换行;而Java则恰好相反,提倡左大括号不换行,以提高代码排版的密度便于阅读。实际上两者各有各的好处,我们使用不同的编程语言开发就要入乡随俗,遵循一个大多数人都认可的标准,这样也省去了调试开发工具的代码格式化器的麻烦。

命名空间

C#中,命名空间相当于Java的包(package)。

上面的例子程序中,有这样一句:

using System;

因为我们要使用System.Console这个类的WriteLine()函数,因此引入了System这个命名空间。如果不引入,我们使用Console时,就必须写它的全限定类名System.Console.WriteLine()了。

对于我们自己的代码,创建命名空间则需要使用namespace关键字:

namespace Gacfox.Demo.DemoNetCore
{
  namespace Project {}
}

namespace可以用大括号嵌套,命名规则通常约定为公司名.项目名.子系统名,其中是可以包含点号的,例如:namespace Gacfox.DemoProject.FirstDemo {}。另外要注意,命名空间要遵循首字母大写的规范。

C#10版本引入了文件全局命名空间的语法:

namespace Gacfox.Demo.DemoNetCore;

在文件开头这样编写,该文件的所有代码就都会位于Gacfox.Demo.DemoNetCore命名空间下,这种写法更加简洁,避免了太多无意义的大括号嵌套因此可读性更好,推荐在高版本的C#开发中使用。不过注意该语法在同一个文件中不可以和大括号语法混合使用。

C#命名空间和Java包的区别:Java的包结构和源代码结构都统一使用文件路径与文件名组织,简单粗暴而且高效;C#使用namespace关键字组织命名空间结构,而源代码路径则由构建工具搜索识别,类名和.cs文件名也可以不同,更加灵活。

代码注释

C#支持3种风格的注释:单行注释、多行注释和XML文档注释。

单行注释使用两个斜线表示,例子如下。

// 这是单行注释

多行注释使用一对/* */表示,其中的内容可以跨越多行。

/*
  这是
  多行
  注释
*/

C#的XML文档注释使用三个斜线///开头,所谓的文档注释类似Java的JavaDoc注释,标注在类和方法上用于生成API文档,在Visual Studio中编写良好的文档注释也会以恰当的方式在代码自动补全框中展现。和Java不同的是C#的文档注释内部包含一系列XML标签来指定文档的各个字段。比较常用的文档注释例子如下:

/// <summary>
/// 两个 <see langword="int" /> 类型整数相加,返回其结果。
/// </summary>
/// <param name="a">被加数</param>
/// <param name="b">加数</param>
/// <returns>两个整数之和</returns>
int Add(int a, int b) { }
  • <summary>:该标签包含函数的摘要信息,该字段应尽量简短的一句话描述函数的功能。
  • <param name="">:该标签描述函数的参数信息,name属性为参数名。
  • <returns>:该标签描述函数的返回值。

上面注释中,我们还用到了<see>标签,它用于在说明中插入,该标签支持两个属性:

  • langword:用于引用C#关键字,常用的包括类似trueint等。
  • cref:用于引用自定义类型,必要时还需要引入类的命名空间。

实际上,C#的文档注释功能是十分强大的,除了上述提到的几种标签,还有许多其它有用的标签:

  • <remarks>:类似于<summary>,用于附加说明,内部可以用<para>标签进行文本的分段。
  • <code lang="">:用于附加使用示例代码,code属性标注语言,用于指示API文档渲染时的代码高亮。

C#的文档注释固然功能强大,但实际使用起来,如果把上面提到的所有标签都在每一个函数上完整的编写,可能造成一个C#源代码文件里充斥丑陋的XML标签,可读性反而很低的窘境。良好的代码应该是自描述的,我们实际开发中应该适度注释,避免像网络小说水字数一样无意义的占用篇幅。

作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。
Copyright © 2017-2024 Gacfox All Rights Reserved.
Build with NextJS | Sitemap