只会记录与其他语言稍有不同或者说特有的部分,因为一门编程语言,相同的功能可能表现形式不同,可能为了更加简便提供类似语法糖的特性。

简介

  1. C#是一门面向对象的编程语言。
  2. Mono是.net框架的一个跨平台的开源版本,可以运行在Linux,Windows,Android,Mac OS等操作系统之上。

环境搭建

  1. 打开VisualStudio Installer,进行以下的安装:


  2. 安装完成以后,在CMD窗口下查看.NET SDK.NET runtimes的安装位置
dotnet --info

.NET SDKs installed:
  8.0.204 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 8.0.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 8.0.4 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 8.0.4 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

数据类型

在C#中变量包含以下几种类型

  1. 值类型
  2. 引用类型
  3. 指针类型
值类型
  1. bool
  2. byte
  3. char:占两个字节
  4. decimal:16个字节
  5. double
  6. float
  7. int
  8. long
  9. sbyte
  10. short
  11. uint
  12. ulong
  13. ushort
  14. Nullable:可空类型允许值类型具有一个附加的值null,可空类型的简写形式为T?
    1. 可空类型本质上是一个泛型结构,包含两个属性
      1. HasValue:指示当前对象是否有值
      2. Value:当HasValue为True时获取对象的值,否则返回null
    2. 示例如下:
    int? x = null;  // 等同于Nullable<int> x = new Nullable<int>(3);
    if (x.HasValue)
    {
        Console.WriteLine(x.Value);
    } else
    {
        Console.WriteLine(x == null);   // True
    }
    
引用类型

内置的引用类型有:

  1. Object
  2. Dynamic
  3. String:
    1. C#中的原生字符串(逐字字符串)的定义方式是在字符串前面加上@符号,有了原生字符串,不需要使用转义字符
指针类型

声明指针类型的语法为:type* identifier

变量

  1. var关键字:用于隐式类型局部变量的声明。它允许编译器在编译时自动推断变量的类型,从而简化代码书写。使用var声明的变量在初始化时必须被赋值,因为类型在那时就被确定下来。

运算符

  1. 空条件运算符?.:用于简化对可能为null的对象的访问操作,其运算符的结果是可空类型Nullable
string str = null;
int? length = str?.Length;
Console.WriteLine(length == null);  // True

str = "Hello World";
length = str?.Length;
Console.WriteLine(length);          // 11

  1. 空合并运算符??:常和空条件运算符一起使用,用于为可空类型和引用类型提供默认值
string str = null;
int? length = str?.Length ?? 0;

Console.WriteLine(length);          // 0

类型转换

  1. 隐式类型转换
  2. 显式类型转换
  3. 使用 Convert 类的方法
  4. 使用Parse 方法和 TryParse 方法

封装

c#中的封装通过访问修饰符来实现

  1. public:所有当前类的对象都可以访问
  2. internal:同一个程序集的对象可以访问,同一个程序集表示同一个DLL或者同一个exe。使用示例:乙方向甲方提供一个DLL,不希望DLL中的部分类可见,则可以使用internal进行类的修饰。
internal class Test { 
    private int x = 10;

    public int GetX()
    {
        return x;
    }
}

public class Program
{
    public static void Main()
    {
        Test test = new Test(); // itis ok
        Console.WriteLine(test.GetX());
    }
}
  1. protected:只有该类对象及其子类对象可以访问
  2. private:对象本身在对象内部可以访问

方法

参数传递
  1. 值参数
  2. 引用参数:在 C# 中,使用 ref 关键字声明引用参数,这种参数既可以表示输入参数,也可以表示输出参数。
public class Program
{
    public static void swap(ref int a, ref int b)
    {
        int temp = a;
        a = b;
        b = temp;
    }
    public static void Main()
    {
        int a =10, b = 20;
        Console.WriteLine("Before swapping: a = {0}, b = {1}", a, b);
        // a,b传入时必须初始化
        Program.swap(ref a, ref b);
        Console.WriteLine("After swapping: a = {0}, b = {1}", a, b);
        Console.ReadLine();

    }
}
  1. 输出参数:这种方式可以返回多个值。在 C# 中,使用out关键字声明输出参数
public class Program
{
    public static void set(out int a)
    {
        // a传出时必须赋值
        a = 1024;
    }
    public static void Main()
    {
        int a = 100;
        Console.WriteLine(a);
        set(out a);
        Console.WriteLine(a);       
    }
}
匿名方法

匿名方法是没有名字的方法

  1. Lambda表达式:用于创建匿名函数,语法如下
// 不需要指定返回类型,他是从方法体内的return语句推断的
(parameters) => {statement}
  1. 示例如下:
Func<int, int, int> add = (a, b) => a + b;
Console.WriteLine(add(2, 3)); 

数组

  1. 参数数组:用于传递未知数量的参数给函数,通常作为函数形参,使用关键字params进行参数化数组的声明
public static int sum(params int[] arr)
{
    int result = 0;
    foreach(int i in  arr)
    {
        result += i;
    }
    return result;
}
static void Main(string[] args)
{
    Console.WriteLine(sum(1, 2, 3, 4, 5));
    Console.ReadKey();
}

字符串

结构体

枚举

  1. 使用class关键字定义类时,如果不指定访问标识符,则默认为internal。而定义类中的成员变量或者成员方法时,成员的默认访问标识符为private

运算符重载

继承

  1. base关键字的使用:父类对象在子类对象创建之前被创建,因此应当在子类的构造函数中使用成员初始化列表进行父类的初始化
位于子类的构造函数示例
public Person(string name, int age, double height) : base(height) {
    this.name = name;
    this.age = age;
}
  1. 如何让类不能被继承:使用sealed关键字进行类的修饰
  2. 如何让类中的方法被子类重写:使用sealed关键字进行方法的修饰

多态

同一种行为具有不同的表现。

  1. 静态期多态:通过函数重载或者运算符重载实现
  2. 运行期多态:和其他面向对象的编程语言一样,需要具备三要素
    1. 存在继承关系
    2. 存在虚函数重写
    3. 父类引用指向子类对象
    4. 示例如下:
    using System;
    using System.Collections.Generic;
    
    namespace test_c
    {
        abstract class Shape
        {
            public abstract double Area();
            private string name;
            public string Name
            {
                get { return name; }
                set { name = value; }   
            }
            public Shape(string name)
            {
                this.name = name;
            }
        }
        sealed class Rectangle : Shape
        {
            private double length;
            private double width;
            public Rectangle(double length, double width, string name): base(name)
            {
                this.length = length;
                this.width = width;
            }
            public override double Area()
            {
                return length * width;
            }
        }
        sealed class Circle : Shape
        {
            private double radius;
            public Circle(double radius, string name): base(name)
            {
                this.radius = radius;
            }
            public override double Area()
            {
                return Math.PI * radius * radius;
            }
        }
        class Caller
        {
            public static void getArea(Shape shape)
            {
                Console.WriteLine("Shape Name: " + shape.Name);
                Console.WriteLine("Area: " + shape.Area());
            }
        }
        class Application
        {
            static void Main(string[] args)
            {
                var shaps = new List<Shape> { new Rectangle(5, 10, "Rectangle"), new Circle(3, "Circle") };
                foreach (var shape in shaps)
                {
                    Caller.getArea(shape);
                }
            }
        }
    }
    

接口

异常处理

文件操作