C#为应付期末涉及到大部分考点所设计的学生管理系统

设计一个学生管理系统:

  • 类图

在这里插入图片描述

  • 涉及知识点:

    1. 面向对象基础(
      封装:Getter、Setter
      继承:显式实现是接口、隐式实现接口、base、this、方法的重载和重写
      多态:虚方法
    2. 几个类似指针的东西:ref、out、params、delegate
    3. 文件操作
    4. 几个常用接口:IComparable IComparer
    5. 常用数据结构:List、Dictionary
    6. 匿名内部类、lamba表达式、LINQ
    7. 重载运算符
  • 需求分析:

    1. 能过实现增删改查(查询使用委托+Lambda+LINQ)
    2. 数据持久化(文件操作)
    3. 排序功能实现(IComparable IComparer)
  • 收获:

    1. Getter和Setter的用法:
      把方法直接看成变量来使用例如给student.id赋值 student.id = 1 打印student.id Console.WriteLine(student.id)
      Getter、Setter必须紧跟在变量名后

    2. Getter和Setter会给默认实现:

      protected int id { get; set; } ===>
      
      public int id
      {
          get
          {
              return this.id;
          }
          set
          {
              id = value;
          }
      }	
      
    3. 重写方法必须要加上override关键字

      public override string ToString()
      {
          return this.id + " " + this.name + " " + this.age;
      }
      
    4. 重写Equals方法要注意
      首先使用as关键字进行类型转化,as比强转更安全,如果不能强转会返回null
      其次记得加上override
      最后return判断条件

    5. C#没有super关键字,继承父类的构造方法使用base

      public Student(int id, string name, int age) : base(id, name, age) { }
      
    6. 运算符重载

      public static Student operator +(Student a, Student b) 
      {
          Student s = new Student();
          s.Id = a.Id + b.Id;
          s.Age = a.Age + b.Age;
          return s;
      }
      
    7. 析构函数不能用public修饰~StudentManager()

    8. 委托其实就是函数指针,使用方式:
      声明一个函数指针指向一个对应的函数

      Select select = DelegateUtils.SelectSample;
      

      通过这个函数指针调用指向的函数

      select(students, id);
      
    9. ref和out相当于指针标志*,但区别在于out类型必须在函数中强制赋值,不然会报错。例如这两个函数:

         public bool Delete(int id, out Student student)
         {
             student = SelectById(id);
             if(student == null)
             {
                 Console.WriteLine("查无此人");
                 return false;
             }
             students.Remove(student);
             return true;
         } 
      
         public bool Update(ref Student student, string name, int age)
         {
             student.name = name;
             student.age = age;
             return true;
         }
      
      
    10. 文件操作使用FileInfo获取文件的信息,使用StreamReader和StreamWriter进行IO操作

      public void Load()
      {
          string path = @"../../../student.txt";
          FileInfo fileInfo = new FileInfo(path);
          if (!fileInfo.Exists)
              fileInfo.Create().Close();//创建文件。Close()关闭流并释放与之关联的所有资源
          StreamReader reader = new StreamReader(path);
          while (reader.Peek() != -1)//判断文件中是否有字符
          {
              string str = reader.ReadLine();
              string[] infos = str.Split(" ");
              Student student = new Student(Convert.ToInt32(infos[0]), infos[1], Convert.ToInt32(infos[2]));
              students.Add(student);
          }
          reader.Close();
      }
      
      public void Store()
      {
          string path = @"../../../student.txt";
          FileInfo fileInfo = new FileInfo(path);
          if (!fileInfo.Exists)
              fileInfo.Create().Close();//创建文件。Close()关闭流并释放与之关联的所有资源
          StreamWriter writer = new StreamWriter(path);
          foreach(Student student in students)
          {
              writer.WriteLine(student.ToString());
              writer.Flush();//刷新缓存
          }
          writer.Close();
      }
      
    11. Action委托是一个没有返回值的委托,<>中可以声明传入参数的个数类型

    12. Lambda表达式和Java中一样只不过使用=> 来表示,而且Lambda表达式只能用于委托类型

      public static Student SelectLambda(List<Student> students, int id)
      {
          Student ans = null;
          Action<int> action = new Action<int>((int id) => {
              foreach (Student student in students)
              {
                  if (student.id == id)
                  {
                      ans = student;
                      break;
                  }
              }
          });
          action(id);
          return ans;
      }
      
    13. LINQ类似于数据库的SQL语句均由三部分构成:
      - 获取数据源
      - 建立查询表达式
      - 执行查询

      	var temp = from student in students //建立结果集
      	                where student.id == id   //查询条件
      	                select student;          //执行查询
      
  • 源代码

using System;
using System.Collections.Generic;
using System.Text;

namespace StudentLib.src
{
    //抽象类   人
    //其实这个类没必要只不过想涉及到继承的知识点
    abstract class Person
    {
        //Getter和Setter紧跟在属性后面
        public int id { get; set; }
        public string name { get; set; }
        public int age { get; set; }

        public Person(){}

        public Person(int id, string name, int age)
        {
            this.id = id;
            this.name = name;
            this.age = age;
        }

        //重载时注意要有override关键字
        public override string ToString()
        {
            return this.id + " " + this.name + " " + this.age;
        }
        public override bool Equals(object obj)
        {
            Person p = obj as Person;
            return this.id == p.id;
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
    }
}
using System;
using System.Collections.Generic;
using System.Text;

namespace StudentLib.src
{
    //学生类
    //继承采用冒号:,多继承用逗号分割
    class Student : Person, IComparable
    {
        public Student() { }

        //使用base调用父类的构造函数
        public Student(int id, string name, int age) : base(id, name, age) { }

        public int CompareTo(object obj)
        {
            Student student = obj as Student;
            return this.id - student.id;
        }

        //使用operator来重载运算符
        public static Student operator +(Student a, Student b) 
        {
            Student s = new Student();
            s.id = a.id + b.id;
            s.age = a.age + b.age;
            return s;
        }

    }
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace StudentLib.src
{
    //学生管理类
    class StudentManager
    {
        //声明委托
        public delegate Student Select(List<Student> students, int id);
        //用于存储学生的集合
        List<Student> students = new List<Student>();

        //构造函数,调用构造函数时从文件中读取数据初始信息
        public StudentManager()
        {
            Load();
        }

        //增
        public bool Insert(Student student) 
        {
            students.Add(student);
            return true;
        }

        //删     这里是为了使用out的知识点所以参数上声明了一个out
        public bool Delete(int id, out Student student)
        {
            student = SelectById2(id,DelegateUtils.SelectSample);
            if(student == null)
            {
                Console.WriteLine("查无此人");
                return false;
            }
            students.Remove(student);
            return true;
        } 
            
        //改     这里是为了使用ref的知识所以参数上使用了一个ref
        public bool Update(ref Student student, string name, int age)
        {
            student.name = name;
            student.age = age;
            return true;
        }

        //查     这里是为了使用委托所以查询采用委托的方式获取
        public Student SelectById(int id)
        {
            
            // Select select = DelegateUtils.SelectSample;
            // Select select = DelegateUtils.SelectLambda;

            Select select = DelegateUtils.SelectLINQ; // 声明委托变量并指向目标函数
            //调用委托函数
            return select(students, id);
        }

        //查     这里将委托作为参数传入
        public Student SelectById2(int id, Select select)
        {
            //调用委托函数
            return select(students, id);
        }

        //根据id进行排序,是让Student实现IComparable的CompareTo方法
        public void SortById()
        {
            students.Sort();
        }

        //根据age排序,是new一个比较器的方式实现,通过StudentCompater实现IComparer的Compare方法
        public void SortByAge(IComparer<Student> comparer)
        {
            students.Sort(comparer);
        }

        //遍历
        public void Show()
        {
            foreach(Student student in students) 
            {
                Console.WriteLine(student);
            }
        }

        //从文件中加载数据
        public void Load()
        {
            string path = @"../../../student.txt";
            FileInfo fileInfo = new FileInfo(path);
            if (!fileInfo.Exists)
                fileInfo.Create().Close();//创建文件。Close()关闭流并释放与之关联的所有资源
            StreamReader reader = new StreamReader(path);
            while (reader.Peek() != -1)//判断文件中是否有字符
            {
                string str = reader.ReadLine();
                string[] infos = str.Split(" ");
                Student student = new Student(Convert.ToInt32(infos[0]), infos[1], Convert.ToInt32(infos[2]));
                students.Add(student);
            }
            reader.Close();
        }

        //数据持久化 将内存中的数据存到磁盘
        public void Store()
        {
            string path = @"../../../student.txt";
            FileInfo fileInfo = new FileInfo(path);
            if (!fileInfo.Exists)
                fileInfo.Create().Close();//创建文件。Close()关闭流并释放与之关联的所有资源
            StreamWriter writer = new StreamWriter(path);
            foreach(Student student in students)
            {
                writer.WriteLine(student.ToString());
                writer.Flush();//刷新缓存
            }
            writer.Close();
        }
    }
}
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Text;

namespace StudentLib.src
{
    //比较器
    class StudentCompater : IComparer<Student>
    {
        public int Compare([AllowNull] Student x, [AllowNull] Student y)
        {
            return x.age - y.age;
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace StudentLib.src
{
    //实现委托的工具类
    class DelegateUtils
    {
        //简单的查询
        public static Student SelectSample(List<Student> students, int id)
        {
            foreach (Student student in students)
            {
                if (student.id == id) return student;
            }
            return null;
        }

        //通过Action和Lambda表达式查询
        public static Student SelectLambda(List<Student> students, int id)
        {
            Student ans = null;
            Action<int> action = new Action<int>((int id) => {
                foreach (Student student in students)
                {
                    if (student.id == id)
                    {
                        ans = student;
                        break;
                    }
                }
            });
            action(id);
            return ans;
        }

        //通过LINQ查询
        public static Student SelectLINQ(List<Student> students, int id)
        {
            var temp = from student in students //建立结果集
                       where student.id == id   //查询条件
                       select student;          //执行查询

            foreach (Student student1 in temp)
            {
                return student1;
            }

            return null;
        }
    }
}
using System;
using System.Collections.Generic;
using StudentLib.src;

namespace StudentLib
{
    class Program
    {
        static void Main(string[] args)
        {
            StudentManager manager = new StudentManager();

            int bottom = 1;
            while (bottom != 0)
            {
                int index = 0;
                Console.WriteLine("=========欢迎来到学生管理系统========");
                Console.WriteLine($"{index++}. 退出学生管理系统");
                Console.WriteLine($"{index++}. 添加学生");
                Console.WriteLine($"{index++}. 删除一个学生");
                Console.WriteLine($"{index++}. 修改一个学生信息");
                Console.WriteLine($"{index++}. 查询一个学生信息");
                Console.WriteLine($"{index++}. 展示学生信息");
                Console.WriteLine($"{index++}. 根据id给学生信息排序");
                Console.WriteLine($"{index++}. 根据age给学生信息排序");
                Console.WriteLine($"{index++}. 保存学生信息");
                Console.WriteLine("请输入您的指令");
                bottom = Convert.ToInt32(Console.ReadLine());
                
                switch (bottom)
                {
                    
                    case 0:
                        Environment.Exit(0);
                        break;
                    case 1:                        
                        manager.Insert(new Student(new Random().Next(), "张三", new Random().Next()));
                        break;
                    case 2:
                        Console.WriteLine("请输入要删除的学生id");
                        int id = Convert.ToInt32(Console.ReadLine());
                        Student student = new Student();
                        manager.Delete(id, out student);
                        Console.WriteLine(student);
                        break;
                    case 3:
                        Console.WriteLine("请输入要修改的学生id");
                        id = Convert.ToInt32(Console.ReadLine());
                        student = manager.SelectById2(id,DelegateUtils.SelectLambda);
                        Console.WriteLine("请输入要修改的学生姓名");
                        string name = Console.ReadLine();
                        Console.WriteLine("请输入要修改的学生年龄");
                        int age = Convert.ToInt32(Console.ReadLine());
                        manager.Update(ref student, name, age);
                        Console.WriteLine(student);
                        break;
                    case 4:
                        Console.WriteLine("请输入要查询的学生id");
                        id = Convert.ToInt32(Console.ReadLine());
                        student = manager.SelectById(id);
                        Console.WriteLine(student);
                        break;
                    case 5:                        
                        manager.Show();
                        break;
                    case 6:
                        manager.SortById();
                        break;
                    case 7:
                        manager.SortByAge(new StudentCompater());
                        break;
                    case 8:
                        manager.Store();
                        break;
                }

            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值