c# - 如何为学生和多门类(class)成绩创建字典?

标签 c# list dictionary generics

我正在学习 C# 字典,但我很困惑如何做到这一点

我有一本学生姓名词典。我想为此分配另一本字典。

我的输入与此类似

学生1: 数学,9 科学,5 英语,2

学生2: 数学,9 科学,10 英语,7

我尝试创建一个名为 Info 的类,这是我的代码

    public class Info
    {
        public string course { get; set; }
        public int grade { get; set; }

        public Info(string c, int g)
        {
            course = c;
            grade = g;
        }

        internal IDictionary<string, Info> infoDic { get; private set; }

        public void Set(string Sname, string course, int grade)
        {
            Student s = new Student(Sname);
            var infor = new Info(course, grade);
            infoDic = new Dictionary<string, Info>();
            infoDic.Add(s.Name, infor);

            //return infoDic;
        } 

        public Dictionary<string, Info> retrieve (string name)
        {
            Student s = new Student(name);
            return infoDic;
        }
    }
}

这是另一种尝试:

我尝试创建类 Info ,主要是创建字典并给出值,但问题是我有 3 门类(class)和 10 名学生,有时我只需要检索所有学生的数学成绩学生。

如何改进代码以区分类(class)?或者如何将类(class)名称作为另一个键?

public class Info
    {
        public string course { get; set; }
        public int grade { get; set; }

        public Info(string c, int g)
        {
            course = c;
            grade = g;
        }

    }


    class Test
    {
        public static void Main(string[] args)
        {

            Dictionary<string, Info> information = new Dictionary<string, Info>();
            Info i1 = new Info("math", 9);
            information.Add("Student1", i1);
            Info i2 = new Info("science", 11);
            information.Add("Student1", i2);
            Info i3 = new Info("math", 13);
            information.Add("student2", i3);

            foreach (KeyValuePair<string, Info> eee in information)
            {
                Console.WriteLine("{0}\t{1}\t{2}", eee.Key, eee.Value.type, eee.Value.count);
            }

        }
    }

我需要两种方法,一种是设置用户输入的值,另一种是在用户需要时检索特定类(class)值

有什么建议吗?

最佳答案

将问题分解为单独的关注点。

使用StudentInfo类只是为了存储数据。重要的是,每个学生都拥有自己的类(class)集合。

public class Student {

    public Student(string name) {
        Name = name;
        Infos = new List<Info>();
    }

    public string Name {get; set;}

    public ICollection<Info> Infos {get; set;}
}

public class Info {
    public Info(string course, int grade) {
        Course = course;
        Grade = grade;
    }

    public string Course { get; set; }
    public int Grade { get; set; }
}

数据访问由不同的类处理 StudentRepository 。 中央词典的类型为 IDictionary<string, Student>以学生姓名作为键并隐藏在存储库中。

using System.Linq;

public class StudentRepository {
    public StudentRepository() {
       _studentsByName = new Dictionary<string, Student>();
    }

    // keep data store private so we can change the implementation
    private IDictionary<string, Student> _studentsByName {get; set;}

    public void Add(Student student) {
        if (_studentsByName.ContainsKey(student.Name)) {
           throw new ArgumentException($"Student '{student.Name}' already stored.");
        }
        _studentsByName.Add(student.Name, student);
    }

    public Student Get(string studentName) {
        if (_studentsByName.ContainsKey(studentName)) {
           return _studentsByName[studentName];
        }
        throw new ArgumentException("No student '" + studentName + "' stored.");
    }

    // Find Grade for certain student and course
    public int GetGrade(string studentName, string course) {
        if (_studentsByName.ContainsKey(studentName)) {
            var student = _studentsByName[studentName];
            var courseInfo = student.Infos.FirstOrDefault(i => i.Course == course);
            if (courseInfo != null) {
                return courseInfo.Grade;
            }
            else {
                throw new ArgumentException(
                    $"Student '{studentName}' did not take the course '{course}'.");
            }
        }
        else {
            throw new ArgumentException($"No student '{studentName}' found.");
        }
    }

    // Get dictionary of all students that took a certain course. Key: student name
    public IDictionary<string, Info> GetCoursesByStudentName(string course) {

        // Use LINQ to retrieve the infos you need. 
        // Here I create a new dictionary with Student name as Key and 
        // the first matching course info found as value.
        // (Students that did not take this course are not in this dictionary):
        return _studentsByName 
            .Where(kvp => kvp.Value.Infos.Any(i => i.Course == course))
            .ToDictionary(kvp => kvp.Key, 
                          kvp => kvp.Value.Infos.First(i => i.Course == course));
    }
}

使用示例:

const string MathCourseName = "Math";

var Student1 = new Student("Alice");
Student1.Infos.Add(new Info(MathCourseName, 4));

var Student2 = new Student("Bob");
Student2.Infos.Add(new Info(MathCourseName, 2));

var Student3 = new Student("Cesar");
Student3.Infos.Add(new Info("English", 3));

var repository = new StudentRepository();

repository.Add(Student1);
repository.Add(Student2);
repository.Add(Student3);

foreach(var kvp in repository.GetCoursesByStudentName(MathCourseName)) {
    Console.WriteLine(kvp.Key + ": " + kvp.Value.Course + " - " + kvp.Value.Grade); 
}

var bobsMathGrade = repository.GetGrade("Bob", MathCourseName);
Console.WriteLine("Bobs math grade: " + bobsMathGrade); 

C# Fiddle for this example

关于c# - 如何为学生和多门类(class)成绩创建字典?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47567171/

相关文章:

c# - EF 3.1 : Overcome LINQ GroupBy SQL translation problem

list - Pyspark 多个列表中每个元素的平均值

python - 加速python中的代码块

python - 从python中的嵌套字典中提取值

c# - WebAPI 在 IIS 中不返回 xml

c# - 如果语句 ||或者 &&

c# - 在 ASP.NET 4.5 和 5.0 项目的 VSTS 发布管理中使用配置变量

java - 从列表中删除 java 类

Python 字典中数组的交集

c++ - 为什么 map 需要实现 'operator<',然后如何比较对象?