最近在做一些需要用到 C# 开发的项目,许久未碰有些生疏,因此决定把语言的基础内容先都快速过一遍。为方便查阅,挑选最精简的部分整理于该博客。
【说明】
- 本系列的目标是整理出十个左右的博客(传送门),其中每个博客大概包含 10 个左右的非常简短的 Section,适合快速入门。目前更新到:精简 C# 入门(三)
- 本系列不适用于编程初学者(未接触任何计算机语言),这一类读者建议仔细学习【参考资料】中的视频资源
【参考资料】
1.b站:【01_C#入门到精通】新手强烈推荐:C#开发课程,一整套课程
2.知乎:C#入门到进阶资源汇总
#1 函数(方法)
1.1 声明 & 调用
函数的声明
[public] static 返回值类型 函数名([参数列表])
{
// 代码块
}
- 我们将用
static
关键字修饰的函数称之为静态函数,相反的,如果不用则称之为非静态函数,这两者有相当显著的区别,详见 博客园:C#中静态与非静态方法比较 - 返回值类型除了
int
,string
等之外,还可以使用空类型void
。返回值为空类型的函数可以不写return
或者用return
来表示函数的执行结束
以 (C#) 精简 C# 入门(一)Section 4 中的一段代码为例:
class Program
{
public static int GetMax(int n1, int n2)
{
return n1 > n2 ? n1 : n2;
}
}
函数的调用
类名.函数名([参数列表])
示例:
int max = Program.GetMax(1, 2);
其他注意事项
对于一个函数而言,其功能单一并不是缺点,反而是基本要求。
1.2 参数 out
, ref
, params[]
out
输出参数: 使函数能够返回多个类型的值。语法:
[public] static 返回值类型 函数名([参数列表], out 返回值类型 变量名, ...)
示例:
class Program
{
static void Main(string[] args)
{
string str = null;
double n = Program.Test(519, out str);
Console.WriteLine(“{
0}, {
1}", str, n);
Console.ReadKey();
}
static double Test(double n1, out string str1)
{
str1 = "Hello World";
return n1 + 1
}
}
>>>
"Hello World 520"
ref
引用参数:使函数内对变量的更改在函数外仍有效。语法:
[public] static 返回值类型 函数名([参数列表], ref 返回值类型 变量名, ...)
示例:
class Program
{
static void Main(string[] args)
{
int n = 0;
Program.Add_1(n);
Console.WriteLine(n);
Program.Add_2(ref n);
Console.WriteLine(n);
Console.ReadKey();
}
// 不使用 ref
static void Add_1(int n1) {
n1 += 1; }
// 使用 ref
static void Add_2(ref int n1) {
n1 += 1; }
}
>>>
"0
1"
params[]
可变参数数组:将输入参数中与可变参数数组类型一致的元素,均当做数组的元素。可变参数数组只能作为输入参数列表中的最后一个元素,示例:
class Program
{
static void Main(string[] args)
{
Program.studentScore("小红", 98, 100, 99);
Program.studentScore("小白", 65, 32); // 第三次弃考无成绩
Console.ReadKey();
}
static void studentScore(string name, params int[] scores)
{
int sum = 0;
for (int i = 0; i < scores.Length; i++) {
sum += scores[i]; }
Console.WriteLine("{0}'s all score: {1}", name, sum);
}
}
>>>
"小红's all score: 297
小白's all score: 97"
当然,如果直接填 int[]
类型的数组也是 OK 的
1.3 重载 & 递归
重载:
重载指的是多个名称相同,但参数不同的函数(返回值类型不需要相同),使得计算机能够根据输入参数的类型以及个数,来选择相应的需要执行的函数。
示例:以下代码中对 Add
函数的重载使其既可以读取 double
类型的数据,也可以读取 string
来进行相加操作
class Program
{
static void Main(string[] args)
{
double r1 = Add(1, 2);
double r2 = Add("1", "2");
Console.WriteLine("Add double: {0}", r1);
Console.WriteLine("Add string: {0}", r2);
Console.ReadKey();
}
static double Add(double n1, double n2)
{
return n1 + n2;
}
static double Add(string s1, string s2)
{
return Convert.ToDouble(s1) + Convert.ToDouble(s2);
}
}
重载存在限制:
- 如果参数个数相同,那么参数类型就不能相同
- 如果参数类型相同,那么参数个数就不能相同
递归:
自己调用自己。示例:
class Program
{
public static int currentTurn = 0;
static void Main(string[] args)
{
Program.Repeat(3);
Console.ReadKey();
}
static void Repeat(int maxTurn)
{
if (currentTurn < maxTurn)
{
Console.WriteLine("重复一次");
currentTurn++;
Program.Repeat(maxTurn);
}
return;
}
}
>>>
"重复一次
重复一次
重复一次"
1.4 练习
关于函数的上述知识点,【参考资料】(1) 中的视频教程给了非常多很有帮助的练习,传送门:(以下红框内的视频中包含的练习都挺不错的)
#2 飞行棋游戏
仅使用当前所介绍的知识,就足矣写出一款飞行棋游戏,由于内容比较长,建议感兴趣的读者跳转到【参考资料】(1) 中的案例练习,传送门。
作者根据自己的理解写了一个类似功能的游戏,目前还没有做代码优化,因此可以看到将近写了 400 行左右(就效果而言总体满意)。待优化一遍后应该会上传至 github,以下是代码截图以及运行截图:
#3 面向过程 → \to → 面向对象
面向过程:分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现。
面向对象:把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。
以上表述摘自 CSDN: 面向对象与面向过程的本质的区别,个人觉得非常直观易懂。
而在【参考资料】(1) 中,传送门,讲师也提供了几个能够帮助理解面向对象和面向过程差异的例子。例如,分别用这两者来描述“关门”:
我们使用 属性
+ 方法
来描述对象。以三个对象,白炽灯、LED灯、小猫为例:
白炽灯
属性:尺寸(20’’)、价格(5 $)
方法:发光(黄色)
LED灯
属性:尺寸(18’’)、价格(9 $)
方法:发光(白色)
小猫
属性:种类(橘猫)、体重(10kg)、性格(闷骚)
方法:吃喝拉撒、与主人玩
上述三个例子当中,很显然白炽灯与LED灯这两个对象具有非常类似的属性和方法,我们把这样的对象进行进一步的封装,从而抽象出 “类” 这一概念。
#4 类
类就是一个模子,确定了某种对象应该具有的属性和方法,因此对象是通过类来创建的,例如白炽灯与LED灯这两个对象可以由 “灯类” 创建 。
类的代码描述:
[public] class 类名
{
字段;
属性;
方法
}
转载:https://blog.csdn.net/weixin_43728138/article/details/115840788