MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

C#基础语法概览与入门指南

2021-08-242.7k 阅读

C# 基础语法概览与入门指南

变量与数据类型

  1. 基本数据类型
    • 整数类型: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 类型变量赋值时,需要在数字后面加上 fF,以区别于 double 类型。
    • 字符类型char 类型用于表示单个字符,用单引号括起来。
    char myChar = 'A';
    
    • 布尔类型bool 类型只有两个值,truefalse,用于逻辑判断。
    bool isTrue = true;
    bool isFalse = false;
    
  2. 引用数据类型
    • 字符串类型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();
    

运算符

  1. 算术运算符
    • 基本算术运算符:包括 +(加法)、-(减法)、*(乘法)、/(除法)和 %(取模)。
    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。
  2. 比较运算符
    • 比较运算符用于比较两个值,结果为 bool 类型。常见的比较运算符有 ==(等于)、!=(不等于)、>(大于)、<(小于)、>=(大于等于)和 <=(小于等于)。
    int x = 10;
    int y = 20;
    bool isEqual = x == y;
    bool isGreater = x > y;
    
  3. 逻辑运算符
    • 逻辑与(&&):只有当两个操作数都为 true 时,结果才为 true
    bool condition1 = true;
    bool condition2 = false;
    bool result3 = condition1 && condition2;
    
    • 逻辑或(||):只要两个操作数中有一个为 true,结果就为 true
    bool result4 = condition1 || condition2;
    
    • 逻辑非(!):对操作数取反,true 变为 falsefalse 变为 true
    bool result5 =!condition1;
    
  4. 赋值运算符
    • 最基本的赋值运算符是 =,用于将右边的值赋给左边的变量。
    int number = 10;
    
    还有复合赋值运算符,如 +=-=*=/=%= 等。
    int num1 = 5;
    num1 += 3; // 等价于 num1 = num1 + 3;
    

流程控制语句

  1. 条件语句
    • 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 块的代码。
  2. 循环语句
    • 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); 这行代码也会先执行一次。
  3. 跳转语句
    • 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); 这行代码,直接进入下一次循环。

方法

  1. 方法的定义与调用
    • 方法是一组执行特定任务的代码块。方法定义包括方法的访问修饰符、返回类型、方法名和参数列表。
    public int Add(int a, int b)
    {
        return a + b;
    }
    
    这里 public 是访问修饰符,表示该方法可以被其他类访问;int 是返回类型,表示方法返回一个整数;Add 是方法名;(int a, int b) 是参数列表,ab 是方法的参数。 调用方法:
    int result = Add(3, 5);
    
  2. 方法重载
    • 方法重载是指在同一个类中可以有多个方法具有相同的名称,但参数列表不同(参数个数、类型或顺序不同)。
    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);
    
  3. 递归方法
    • 递归方法是指在方法内部调用自身的方法。递归方法需要有一个终止条件,否则会导致无限循环。 例如,计算阶乘的递归方法:
    public int Factorial(int n)
    {
        if (n == 0 || n == 1)
        {
            return 1;
        }
        else
        {
            return n * Factorial(n - 1);
        }
    }
    
    调用 Factorial(5) 时,方法会不断调用自身,直到 n 等于 0 或 1 时返回结果。

面向对象编程基础

  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);
    
  2. 继承
    • 继承允许一个类从另一个类获取成员。被继承的类称为基类,继承的类称为派生类。
    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();
    
  3. 多态
    • 多态是指不同的对象对同一消息做出不同响应的能力。在 C# 中,多态通过虚方法和重写来实现。 继续上面的 ShapeSquare 类的例子,假设有一个 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();
    
    这里 shape1shape2 虽然都是 Shape 类型,但实际调用的 Area 方法是各自派生类中重写的版本,体现了多态性。

异常处理

  1. 异常的概念
    • 在程序执行过程中,可能会出现各种错误,如除以零、访问不存在的文件等。这些错误会导致异常。C# 提供了异常处理机制来捕获和处理这些异常,使程序不会意外终止。
  2. try - catch 语句
    • try 块中包含可能会抛出异常的代码。catch 块用于捕获并处理异常。
    try
    {
        int result = 10 / 0;
    }
    catch (DivideByZeroException ex)
    {
        Console.WriteLine($"Error: {ex.Message}");
    }
    
    这里 try 块中的 10 / 0 会抛出 DivideByZeroException 异常,catch 块捕获到该异常并输出错误信息。
  3. finally 块
    • finally 块无论 try 块中是否抛出异常,都会执行。通常用于释放资源,如关闭文件、数据库连接等。
    try
    {
        // 可能会抛出异常的代码
    }
    catch (Exception ex)
    {
        // 处理异常
    }
    finally
    {
        // 一定会执行的代码
    }
    

泛型

  1. 泛型的基本概念
    • 泛型允许创建可以与不同数据类型一起工作的类、方法和接口。通过使用类型参数,在编译时确定实际的数据类型。
  2. 泛型类
    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();
    
  3. 泛型方法
    • 方法也可以是泛型的。
    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");
    

委托与事件

  1. 委托
    • 委托是一种类型安全的函数指针。它允许将方法作为参数传递给其他方法。
    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);
    
  2. 事件
    • 事件是一种基于委托的机制,用于在特定事件发生时通知其他对象。
    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# 语言。