1.成员定义

成员变量:类中的字段,用于存储数据

成员函数:类中的函数,执行特定任务的语句

局部变量:方法体内的变量,方法中有效,var 能代替任意类型,必须初始化时赋值,且不能更改

值类型:是对类型的副本进行操作,如,基本数据类型,枚举,结构

引用类型:是对类型本体的引用,如,数组,接口,类(基类 Object,delegate,string)

2.可空类型

可空类型表示在基础值类型范围内,加上一个 null 值

1 int ? a = null2 int ? b = 3;
3 int ? c = 5; 
4 int ? result_1 = a ?? b // 返回 3
5 int ? result_2 = c ?? b // 返回 5

3.Foreach 循环

1 int[] array = new int[3]{1,2,3};  // 遍历数组
2 
3 foreach(int n in array)
4 {
5     Console.WriteLine("{0}",n);
6 }

4.方法

 1 class Add
 2 {
 3        public int AddFun(int n) // 访问修饰符,返回值类型,方法名,参数列表,方法主体
 4        {
 5            int result;
 6 
 7            if(n == 1)
 8            {
 9                return 1;
10            }
11            else
12            {
13                return result = n + AddFun(n-1); // 递归调用
14            }
15        }
16 }
17  
18 Add A1 = new Add();  // 实例化后,使用函数名调用函数
19 int result = A1.AddFun(4); // 函数调用
20 
21 Console.WriteLine("{0}",result);

值传递:实参和形参使用的是两个不同内存中的值,形参改变时,不会影响实参的值

引用传递:引用变量的内存位置,引用参数与实际参数具有相同的内存位置,ref 关键字引导,且变量必须初始化

 1 class NumberSwitch
 2 {
 3         public void Switch(ref int a,ref int b) //交换变量
 4        {
 5             int Temp;
 6             Temp = a;
 7             a = b;
 8             b = Temp;
 9         }
10 
11         public void Switch( int a, int b) //函数重载
12        {
13             int Temp;
14             Temp = a;
15             a = b;
16             b = Temp;
17         }
18 }
19          int a = 5; int b = 10;
20          NumberSwitch NS = new NumberSwitch();
21 
22          NS.Switch(a, b);    //值传递
23          Console.WriteLine("{0},{1}",a,b); // 5,10
24 
25          NS.Switch(ref a,ref b); //引用传递
26          Console.WriteLine("{0},{1}",a,b); // 10,5

5.数组

 1 double[] array = new double[2]; // 一维数组
 2 double[] array = new double[1,2] // 二维数组
 3 
 4 array[0] = 1; array[1] = 2; // 索引号单独赋值
 5 
 6 int[] array = {1,2}; // 声明后直接赋值
 7 
 8 int[] array = new int[2] {1,2} //实例化后直接赋值,数组大小可省略
 9 
10 int[] score = array; // 把一个数组变量赋值到另一个数组中,而且指向相同的内存位置

6.字符串

String 变量直接定义,并使用串联运算符

1 string Fname,Lname;
2 Fname = "Zhang"; Lname = "San";
3 
4 string FullName = Fname + Lname ;

通过 string 构造函数

1 char[] letters = { 'H', 'e', 'l', 'l','o' };
2 string welcome = new string(letters);

StringBuilder:通过 Append() 方法,修改字符串时自动扩展(适合大量字符串修改操作)

1 StringBuilder S1 = new StringBuilder();
2 S1.Append("This is a StringBuilder");

7.结构体

可以带有多个成员的新数据类型,如:方法,字段,索引,属性,运算符方法和事件

结构不能继承其他的结构或类,但可以实现一个或多个接口

struct Books
{
     public int id; // 不可赋值
     public string name;
}

     Books B1 = new Books(); // 实例化
     B1.id = 1;
     B1.name = "西游记";

     Console.WriteLine("{0} : {1}", B1.id,B1.name)

8.枚举

使用 enum 命名一组整型常量

1 enum Day { Sun, Mon, Tue, Wed, Thu, Fri, Sat }
2 
3 int x = Convert.ToInt32(Day.Sun); // 默认从0开始
4 
5 Console.WriteLine("{0}", x);

9.类

对象的集合,表示对象由什么组成,可执行什么操作,类中的方法和变量称为类的成员

多重继承:一个子类只能继承一个父类,但可以继承多个接口

 1 class Box // 默认为 internal
 2 {
 3     public double lenth; // 默认为 private
 4     public double breadth;
 5 }
 6     Box box = new Box();
 7     box.length = 10;
 8     box.breadth = 10;
 9     double Square = box.length * box.breadth;
10 
11     Console.WriteLine("{0}", Square);

默认构造函数:初始化类实例,特殊的成员函数,类实例化对象时执行,无返回类型,与类名相同

1 public Box()
2 {
3    Console.WriteLine("对象已被创建");
4 }

析构函数:无返回值,不带参数,有且只有一个,不能继承,用于程序结束之前释放资源

1 ~Box() 
2 {
3  
4 }

10.base

派生类继承基类的方法后,通过 base 实现方法内容,或创建派生类时,调用基类构造函数

 1 class Father
 2 {
 3         protected string sex = "";
 4 
 5         public virtual void GetInfo() // 父类方法
 6         {
 7             Console.WriteLine("{0}", sex);
 8         }
 9 
10         public Father(int i) // 带参构造函数
11         {
12             Console.WriteLine("身高:{0}", i);
13         }
14 }
15 
16 class Son : Father // 子类继承父类
17 {
18         public Son(int i) : base(i) // 通过 base 调用父类构造函数
19         {
20 
21         }
22 
23         public int age = 18;
24 
25         public override void GetInfo() // 重写父类方法
26         {
27             base.GetInfo(); //通过 base 调用父类方法
28             Console.WriteLine("{0}", age);
29         }
30 }
31             Son S1 = new Son(170); // 实例化时,满足带参构造函数格式
32             S1.GetInfo();

11. this

表示当前类的实例,或充当方法的参数

 1 class Tax
 2 {
 3         private static double salary = 3000.00;
 4 
 5         public static double tax(Employee e) // 静态函数
 6         {
 7             return 0.1 * salary;
 8         }
 9 }
10 
11 class Employee
12 {
13         private string name;
14 
15         public Employee(string name) // 构造函数
16         {
17             this.name = name; // 使用 this 代表当前实例
18         }
19 
20         public void PrintInfo()
21         {
22             Console.WriteLine("{0}:{1}", name, Tax.tax(this)); // 在方法中当作参数传递
23         }
24 }
25          Employee E1 = new Employee("Jhon");
26          E1.PrintInfo();

12.堆和栈

引用类型:存储在堆中,类型实例化时,类的实例存储在堆中,类型对象的引用存储在栈中

值类型:值类型和指针分配在它声明的地方,做局部变量时,存储在栈上,做类对象的字段时,存储在堆中

1 Student S1;// S1是对象的引用
2 S1 = new Student(); // 实例化一个对象

托管堆:不同于 C 的堆,由 CLR 管理,当堆满后,自动清理堆中的垃圾

内存堆栈:内存分为栈区和堆区

               :栈区存放函数参数,局部变量,返回值数据,由编译器自动释放

               :堆区存放引用的对象,由CLR释放

装箱:把值类型转换为引用类型,把栈中的值封装起来,放在堆中存储

拆箱:先在栈中开辟一片空间,把堆中的数据复制到栈中

1 int Num_1 = 5;
2 object Num_2 = num_1; // 装箱
3 
4 int Num_3;
5 Num_3 = (int) Num_2; // 拆箱 

13.字段与属性

字段:在类中做数据交互使用,默认为 private

属性:外界访问私有字段的入口,本质是方法不保存数据,对字段进行赋值和读取操作

       :首字母大写表示,默认为 public 

class Student
{
       private int age; // 私有字段

       public int Age // 公有属性
       {
            get // 获取
            {
                if (age < 0) // 避免出现非法数据,或限定字段只读或只写
                    return 18;
                else
                    return age;
            }
            set // 赋值
            {
                age = value;
            }
       }
       public void PrintOut()
       {
            Console.WriteLine("{0}", Age);
       }
}
            Student S1 = new Student();
            S1.Name = -1;
            S1.PrintOut();

14.索引器

索引器可以使类或结构体的实例对象,以数组一样的方式进行索引,不能声明为 static

public class Student
{
       private string[] name = new string[10]; // 定义数组,存储实例化对象

       public string this[int index] // 索引器使用 this 定义,this 就是实例化后的对象
        {                            // 索引类型可以是其他类型
            get
            {
                return name[index];
            }
            set
            {
                name[index] = value;
            }
        }
}
                Student S1 = new Student();
                S1[0] = "ZhangSan";

15.封装

访问修饰符:设置使用者的访问权限,确保数据成员安全

private:只能在在内部访问

protected:只有该类对象和子类对象可以访问

internal:同一个程序集可以访问

protected internal:允许在当前程序集,本类和派生类中访问

public:所有对象都可以访问

16.继承

派生类可以继承基类所有的属性和方法,且可以继承1个基类和多个接口

 1 class Shape // 父类
 2 {
 3       public void setWidth(int w)
 4       {
 5          width = w;
 6       }
 7       protected int width;
 8 }
 9 
10 class Square: Shape // 子类继承父类属性和方法
11 {
12       public int getArea()
13       {
14          return (width *width);
15       }
16 }
17 
18       Square  Rect = new Square();
19       Rect.setWidth(5);
20       Rect.getArea();

17.多态性

多态就是同一个接口,使用不同的实例而执行不同操作

静态性多态:函数重载,运算符重载(不可使用 base 和 this)

函数重载:函数名相同,参数列表不同(数据类型,参数个数,参数顺序)

 1 class Culculate
 2 {
 3         public void Cul(int a, int b) // 累加方法
 4         {
 5             int c = a + b;
 6             Console.WriteLine("{0}", c);
 7         }
 8 
 9         public void Cul(double a, double b) // 函数重载
10         {
11             double c = a * b;
12             Console.WriteLine("{0}", c);
13         }
14 }
15          Culculate C1 = new Culculate();
16          C1.Cul(1, 2);
17          C1.Cul(2.5, 2.5);

动态性多态:使用抽象类和虚方法实现

 1 abstract class Shape // 抽象类:不能有方法体和实例化,只能在抽象类中声明抽象方法,子类必须重写 
 2 {
 3        abstract public int area(); // 抽象方法
 4 }
 5 class Square:  Shape
 6 {
 7       private int length;
 8 
 9       public Square( int a = 0 ) // 构造函数,初始化
10       {
11          length = a;
12       }
13       public override int area () //重写父类方法,类似接口
14       {
15          Console.WriteLine("Square 类的面积:");
16          return (length * length);
17       }
18 }19          Square S1 = new Square();20          Consolo.WriteLine("{0}",S1.arae());
19 
20 
21 public class Shape
22 {
23     public virtual void Draw() // 虚方法:必须有方法体,子类不一定要重写
24     {
25         Console.WriteLine("父类方法"); // 实现部分
26     }
27 }
28 class Circle : Shape
29 {
30     public override void Draw() // 使用 override 重写父类方法
31     {
32         Console.WriteLine("重写父类方法");
33         base.Draw(); // 调用父类方法
34     }
35 }16      Circle C1 = new Circle();17      C1.Draw();

18.接口

 1 interface IClimbTree // 定义爬树接口
 2 {
 3         public void ClimbTree(); //只声明方法
 4 }
 5 
 6 interface ICatchMice // 定义抓老鼠接口
 7 {
 8         void CatchMice();
 9 }
10 
11 class Cat : IClimbTree,ICatchMice // 类继承俩个接口
12 {
13         public void ClimbTree() // 在具体类中重写方法
14         {
15             Console.WriteLine("猫会爬树");
16         }
17         public  void CatchMice()
18         {
19             Console.WriteLine("猫会抓老鼠");
20         }
21 }
22 
23             Cat cat = new Cat();
24             cat.ClimbTree();
25             cat.CatchMice();

19.委托

本质是一个引用类型,对某个方法进行引用,间接调用方法,自身可作参数传递回调函数

 1 public delegate int Delegate(int a, int b); // 定义委托,返回值类型和参数要与调用方法一致
 2 
 3 class Culculator
 4 {
 5          public void Report()
 6          {
 7              Console.WriteLine("Have 3 Methods");
 8          }
 9          public int Add(int a,int b)
10          {
11              return a + b;
12          }
13          public int Sub(int a,int b)
14          {
15              return a - b;
16          }
17 }
18          Culculator culculator = new Culculator();
19 
20          Action action = new Action(culculator.Report); // 内置 Action 委托,适合无返回类型
21          action.Invoke();
22          // 内置 Func 委托,参数列表和返回值类型要对应
23          Func<int, int, int> func = new Func<int, int, int>(culculator.Add);
24          func.Invoke(5, 10); // Invoke() 调用函数
25          Console.WriteLine("{0}", func.Invoke(5, 10));
26 
27          Delegate dele = new Delegate(culculator.Sub); // 自定义委托
28          dele.Invoke(5, 5);
29          Console.WriteLine("{0}",dele(5, 5));

20.事件

事件在类中声明,是类的成员,使对象或类具备通知能力

如:对象 O 拥有事件 E,如果 B 订阅 O,当事件触发时,O 就会通知 B,B 根据事件参数做出反应(可选)

事件拥有者(event source,对象)

事件成员(event,成员)

事件的响应者(event subscriber,对象)

事件处理器(event handler,成员):本质是一个回调方法

事件订阅:把事件处理器与事件相关联,本质是一种委托

 1 using System.Timers; // 内置事件
 2 
 3 static void Main()
 4 {
 5        Timer timer = new Timer(); // 事件拥有者
 6        timer.Interval = 1500; // 时间间隔,单位毫秒
 7 
 8        Boy boy = new Boy(); // 事件响应者
 9 
10        timer.Elapsed += boy.Aciton;    // 订阅事件,Elapsed 为事件
11 
12        timer.Start(); // 计时开始
13        Console.ReadKey();
14 }
15 
16 class Boy
17 {
18        internal void Aciton(object sender, ElapsedEventArgs e) // 事件处理器
19        {
20            Console.WriteLine("触发事件");
21        }
22 }

自定义时间:通过委托关联事件,从而调用函数

 1 public delegate void CatCallEventHandler(); // 定义猫叫委托 CatCallEventHandler()
 2 
 3 public class Cat // 发布器类
 4 {
 5         public event CatCallEventHandler CatCall; // 定义猫叫事件 CatCall
 6         public void Call()
 7         {
 8             Console.WriteLine("猫叫了");
 9             CatCall?.Invoke(); // 事件不为空,则调用
10         }
11 }
12 
13 public class Mouse // 订阅器类
14 {
15         public void Run() // 事件处理器
16         {
17             Console.WriteLine("老鼠跑了");
18         }
19 }
20 
21 public class People // 订阅器类
22 {
23         public void WakeUp() // 事件处理器
24         {
25             Console.WriteLine("人醒了");
26         }
27  }
28 
29          Cat cat = new Cat(); // 事件拥有者
30          Mouse mouse = new Mouse(); // 事件响应者
31          People people = new People();
32 
33          cat.CatCall += new CatCallEventHandler(mouse.Run); // 关联事件
34          cat.CatCall += new CatCallEventHandler(people.WakeUp);
35 
36          cat.Call(); // 触发事件