C#基础语法概览与入门指南
2021-08-242.7k 阅读
C# 基础语法概览与入门指南
变量与数据类型
- 基本数据类型
- 整数类型:C# 提供了多种整数类型,用于表示不同范围的整数值。例如,
byte
类型表示 0 到 255 之间的无符号 8 位整数。
byte myByte = 100;
short
类型是 16 位有符号整数,范围是 - 32,768 到 32,767。short myShort = -1000;
int
类型是最常用的整数类型,为 32 位有符号整数,范围较大,适用于一般整数运算。int myInt = 12345;
long
类型表示 64 位有符号整数,用于表示非常大的整数值。long myLong = 999999999999999999;
- 浮点类型:
float
类型是单精度浮点数,double
类型是双精度浮点数。float
适用于对精度要求不高且需要节省内存的场景,而double
则用于更精确的浮点数运算。
注意,在给float myFloat = 3.14f; double myDouble = 3.141592653589793;
float
类型变量赋值时,需要在数字后面加上f
或F
,以区别于double
类型。- 字符类型:
char
类型用于表示单个字符,用单引号括起来。
char myChar = 'A';
- 布尔类型:
bool
类型只有两个值,true
和false
,用于逻辑判断。
bool isTrue = true; bool isFalse = false;
- 整数类型:C# 提供了多种整数类型,用于表示不同范围的整数值。例如,
- 引用数据类型
- 字符串类型:
string
类型用于表示字符串,即字符序列。可以使用双引号来定义字符串。
字符串是不可变的,一旦创建,其内容不能直接修改。例如,以下代码看似修改了字符串,但实际上是创建了一个新的字符串对象。string myString = "Hello, World!";
string str = "Hello"; str = str + " World";
- 数组:数组是一种数据结构,用于存储多个相同类型的元素。可以通过索引来访问数组中的元素。
也可以在声明数组时初始化元素。int[] numbers = new int[5]; numbers[0] = 1; numbers[1] = 2; // 访问数组元素 int firstNumber = numbers[0];
多维数组也是支持的,例如二维数组。int[] numbers2 = { 1, 2, 3, 4, 5 };
int[,] matrix = new int[2, 3] { { 1, 2, 3 }, { 4, 5, 6 } }; int value = matrix[1, 2];
- 类和对象:类是一种自定义的数据类型,它封装了数据(字段)和行为(方法)。对象是类的实例。 首先定义一个简单的类:
然后创建对象并使用:class Person { public string Name { get; set; } public int Age { get; set; } public void Introduce() { Console.WriteLine($"My name is {Name} and I'm {Age} years old."); } }
Person person = new Person(); person.Name = "John"; person.Age = 30; person.Introduce();
- 字符串类型:
运算符
- 算术运算符
- 基本算术运算符:包括
+
(加法)、-
(减法)、*
(乘法)、/
(除法)和%
(取模)。
在整数除法中,如果结果不是整数,小数部分会被截断。例如,int a = 10; int b = 3; int sum = a + b; int difference = a - b; int product = a * b; int quotient = a / b; int remainder = a % b;
10 / 3
的结果是 3。- 自增和自减运算符:
++
用于自增,--
用于自减。它们可以放在变量之前(前缀形式)或之后(后缀形式)。
前缀形式(如int num = 5; int result1 = num++; int result2 = ++num;
++num
)先将变量值加 1,然后返回新的值;后缀形式(如num++
)先返回变量的当前值,然后再将变量值加 1。所以,上述代码执行后,result1
的值为 5,result2
的值为 7。 - 基本算术运算符:包括
- 比较运算符
- 比较运算符用于比较两个值,结果为
bool
类型。常见的比较运算符有==
(等于)、!=
(不等于)、>
(大于)、<
(小于)、>=
(大于等于)和<=
(小于等于)。
int x = 10; int y = 20; bool isEqual = x == y; bool isGreater = x > y;
- 比较运算符用于比较两个值,结果为
- 逻辑运算符
- 逻辑与(&&):只有当两个操作数都为
true
时,结果才为true
。
bool condition1 = true; bool condition2 = false; bool result3 = condition1 && condition2;
- 逻辑或(||):只要两个操作数中有一个为
true
,结果就为true
。
bool result4 = condition1 || condition2;
- 逻辑非(!):对操作数取反,
true
变为false
,false
变为true
。
bool result5 =!condition1;
- 逻辑与(&&):只有当两个操作数都为
- 赋值运算符
- 最基本的赋值运算符是
=
,用于将右边的值赋给左边的变量。
还有复合赋值运算符,如int number = 10;
+=
、-=
、*=
、/=
、%=
等。int num1 = 5; num1 += 3; // 等价于 num1 = num1 + 3;
- 最基本的赋值运算符是
流程控制语句
- 条件语句
- if - else 语句:根据条件判断执行不同的代码块。
可以有多个int score = 85; if (score >= 60) { Console.WriteLine("Passed"); } else { Console.WriteLine("Failed"); }
else if
子句来进行更复杂的条件判断。if (score >= 90) { Console.WriteLine("A"); } else if (score >= 80) { Console.WriteLine("B"); } else if (score >= 70) { Console.WriteLine("C"); } else if (score >= 60) { Console.WriteLine("D"); } else { Console.WriteLine("F"); }
- switch - case 语句:用于根据一个表达式的值来选择执行不同的代码块。
int dayOfWeek = 3; switch (dayOfWeek) { case 1: Console.WriteLine("Monday"); break; case 2: Console.WriteLine("Tuesday"); break; case 3: Console.WriteLine("Wednesday"); break; default: Console.WriteLine("Other day"); break; }
break
关键字用于跳出switch
语句块。如果没有break
,会继续执行下一个case
块的代码。 - 循环语句
- for 循环:常用于已知循环次数的情况。
这里for (int i = 0; i < 5; i++) { Console.WriteLine(i); }
int i = 0
是初始化部分,i < 5
是条件判断部分,i++
是迭代部分。每次循环开始时,先判断条件,满足条件则执行循环体,然后执行迭代部分,再进行下一次条件判断。- while 循环:只要条件为
true
,就会一直执行循环体。
int count = 0; while (count < 3) { Console.WriteLine(count); count++; }
- do - while 循环:先执行一次循环体,然后再判断条件。所以,无论条件是否满足,循环体至少会执行一次。
这里即使int num2 = 0; do { Console.WriteLine(num2); num2++; } while (num2 < 0);
num2 < 0
条件不成立,Console.WriteLine(num2);
这行代码也会先执行一次。 - 跳转语句
- break 语句:除了在
switch
语句中使用,还可以用于跳出循环。
当for (int j = 0; j < 10; j++) { if (j == 5) { break; } Console.WriteLine(j); }
j
等于 5 时,break
语句会跳出for
循环,后续代码不再执行。- continue 语句:用于跳过当前循环的剩余部分,直接进入下一次循环。
这里当for (int k = 0; k < 10; k++) { if (k % 2 == 0) { continue; } Console.WriteLine(k); }
k
是偶数时,continue
语句会跳过Console.WriteLine(k);
这行代码,直接进入下一次循环。 - break 语句:除了在
方法
- 方法的定义与调用
- 方法是一组执行特定任务的代码块。方法定义包括方法的访问修饰符、返回类型、方法名和参数列表。
这里public int Add(int a, int b) { return a + b; }
public
是访问修饰符,表示该方法可以被其他类访问;int
是返回类型,表示方法返回一个整数;Add
是方法名;(int a, int b)
是参数列表,a
和b
是方法的参数。 调用方法:int result = Add(3, 5);
- 方法重载
- 方法重载是指在同一个类中可以有多个方法具有相同的名称,但参数列表不同(参数个数、类型或顺序不同)。
这样,根据传入参数的类型,编译器会选择合适的方法来调用。public int Add(int a, int b) { return a + b; } public double Add(double a, double b) { return a + b; }
int sum1 = Add(2, 3); double sum2 = Add(2.5, 3.5);
- 递归方法
- 递归方法是指在方法内部调用自身的方法。递归方法需要有一个终止条件,否则会导致无限循环。 例如,计算阶乘的递归方法:
调用public int Factorial(int n) { if (n == 0 || n == 1) { return 1; } else { return n * Factorial(n - 1); } }
Factorial(5)
时,方法会不断调用自身,直到n
等于 0 或 1 时返回结果。
面向对象编程基础
- 类与对象深入
- 字段与属性:字段是类中存储数据的成员。属性是一种特殊的成员,它提供了对字段的访问控制。
这里class Circle { private double radius; public double Radius { get { return radius; } set { radius = value; } } public double Area() { return Math.PI * radius * radius; } }
radius
是私有字段,通过Radius
属性来访问和修改它。get
访问器用于获取字段的值,set
访问器用于设置字段的值。- 构造函数:构造函数是一种特殊的方法,用于创建对象时初始化对象的状态。构造函数的名称与类名相同,没有返回类型。
创建class Rectangle { public double Width { get; set; } public double Height { get; set; } public Rectangle(double width, double height) { Width = width; Height = height; } public double Area() { return Width * Height; } }
Rectangle
对象时,可以通过构造函数传入初始的宽度和高度值。Rectangle rect = new Rectangle(5, 10);
- 继承
- 继承允许一个类从另一个类获取成员。被继承的类称为基类,继承的类称为派生类。
这里class Shape { public string Color { get; set; } public virtual double Area() { return 0; } } class Square : Shape { public double Side { get; set; } public override double Area() { return Side * Side; } }
Square
类继承自Shape
类,它继承了Color
属性和Area
方法。Square
类重写了Area
方法以提供适合正方形的面积计算逻辑。Square square = new Square(); square.Color = "Red"; square.Side = 5; double area = square.Area();
- 多态
- 多态是指不同的对象对同一消息做出不同响应的能力。在 C# 中,多态通过虚方法和重写来实现。
继续上面的
Shape
和Square
类的例子,假设有一个Triangle
类也继承自Shape
类并重写Area
方法。
可以通过基类类型的变量来引用不同派生类的对象,并调用重写的方法。class Triangle : Shape { public double Base { get; set; } public double Height { get; set; } public override double Area() { return 0.5 * Base * Height; } }
这里Shape shape1 = new Square() { Side = 5 }; Shape shape2 = new Triangle() { Base = 4, Height = 6 }; double area1 = shape1.Area(); double area2 = shape2.Area();
shape1
和shape2
虽然都是Shape
类型,但实际调用的Area
方法是各自派生类中重写的版本,体现了多态性。 - 多态是指不同的对象对同一消息做出不同响应的能力。在 C# 中,多态通过虚方法和重写来实现。
继续上面的
异常处理
- 异常的概念
- 在程序执行过程中,可能会出现各种错误,如除以零、访问不存在的文件等。这些错误会导致异常。C# 提供了异常处理机制来捕获和处理这些异常,使程序不会意外终止。
- try - catch 语句
try
块中包含可能会抛出异常的代码。catch
块用于捕获并处理异常。
这里try { int result = 10 / 0; } catch (DivideByZeroException ex) { Console.WriteLine($"Error: {ex.Message}"); }
try
块中的10 / 0
会抛出DivideByZeroException
异常,catch
块捕获到该异常并输出错误信息。 - finally 块
finally
块无论try
块中是否抛出异常,都会执行。通常用于释放资源,如关闭文件、数据库连接等。
try { // 可能会抛出异常的代码 } catch (Exception ex) { // 处理异常 } finally { // 一定会执行的代码 }
泛型
- 泛型的基本概念
- 泛型允许创建可以与不同数据类型一起工作的类、方法和接口。通过使用类型参数,在编译时确定实际的数据类型。
- 泛型类
这里class GenericBox<T> { private T value; public void SetValue(T val) { value = val; } public T GetValue() { return value; } }
T
是类型参数,可以在创建GenericBox
对象时指定实际的数据类型。GenericBox<int> intBox = new GenericBox<int>(); intBox.SetValue(10); int result = intBox.GetValue(); GenericBox<string> stringBox = new GenericBox<string>(); stringBox.SetValue("Hello"); string str = stringBox.GetValue();
- 泛型方法
- 方法也可以是泛型的。
这里class GenericUtils { public static T GetMax<T>(T a, T b) where T : IComparable<T> { if (a.CompareTo(b) > 0) { return a; } else { return b; } } }
GetMax
方法是泛型方法,where T : IComparable<T>
是类型约束,表示T
类型必须实现IComparable<T>
接口,这样才能进行比较操作。int maxInt = GenericUtils.GetMax(5, 10); string maxString = GenericUtils.GetMax("apple", "banana");
委托与事件
- 委托
- 委托是一种类型安全的函数指针。它允许将方法作为参数传递给其他方法。
使用委托:delegate int MathOperation(int a, int b); class Calculator { public int Add(int a, int b) { return a + b; } public int Multiply(int a, int b) { return a * b; } public int PerformOperation(MathOperation operation, int a, int b) { return operation(a, b); } }
Calculator calculator = new Calculator(); MathOperation addOperation = calculator.Add; int sum = calculator.PerformOperation(addOperation, 3, 5); MathOperation multiplyOperation = calculator.Multiply; int product = calculator.PerformOperation(multiplyOperation, 3, 5);
- 事件
- 事件是一种基于委托的机制,用于在特定事件发生时通知其他对象。
这里public delegate void ClickEventHandler(object sender, EventArgs e); class Button { public event ClickEventHandler Click; public void OnClick() { if (Click != null) { Click(this, EventArgs.Empty); } } } class Program { static void Button_Click(object sender, EventArgs e) { Console.WriteLine("Button clicked!"); } static void Main() { Button button = new Button(); button.Click += Button_Click; button.OnClick(); } }
Button
类定义了一个Click
事件,当OnClick
方法被调用时,如果有注册的事件处理程序(通过+=
注册),就会调用相应的处理程序。
通过以上对 C# 基础语法的全面介绍,相信你已经对 C# 编程有了较为深入的了解,可以开始编写自己的 C# 程序了。在实际编程中,不断练习和实践这些知识,将有助于你更好地掌握 C# 语言。