C#组卷开发:List<Gene>转数组失败,求解决方案
Hey,我来帮你搞定这个问题!首先你要知道:Gene[] geneArray = QuestionList.ToArray()这个写法本身是完全正确的,之所以会“失败”,大概率是代码里的其他细节问题拖了后腿,咱们一步步拆解:
一、先搞清楚转数组的正确姿势
你尝试的Gene[] s = QuestionList.ToArray()语法上没有问题——因为List<T>本身就自带ToArray()方法,能直接把集合转成对应类型的数组。如果编译报错,先检查这两点:
- 有没有正确引用
System.Collections.Generic命名空间(一般新建项目都会默认引用) - 是不是拼写错误?比如Gene类名写错,或者QuestionList的声明类型不对?
如果是运行时发现数组是空的,那问题肯定出在QuestionList没有被正确填充,这就要看你读取数据库的代码了。
二、你的数据库读取代码里的坑
我仔细看了你的代码,发现几个关键错误,这些会导致QuestionList数据缺失甚至为空:
1. SQL语句的语法错误
你的SQL里有两处明显错误:
- 开头的
select * Question多了个多余的*,应该直接写select Question, CLO, Question_Type LIMIT = '" + qt.numOfType这里,LIMIT后面不需要=,而且如果qt.numOfType是数字类型,不需要加引号(加了会变成字符串,数据库会报错)
更重要的是:别直接拼接字符串写SQL! 这会有SQL注入风险,一定要用参数化查询。修正后的SQL代码应该是这样:
string sql = "select Question, CLO, Question_Type FROM QuestionBank WHERE Subject = @Subject AND chapter = @Chapter AND Question_Type = @QuestionType ORDER BY RAND() LIMIT @Limit"; SqlCommand cmd = new SqlCommand(sql, con); // 添加参数,避免注入,同时解决类型问题 cmd.Parameters.AddWithValue("@Subject", sub); cmd.Parameters.AddWithValue("@Chapter", chapter); cmd.Parameters.AddWithValue("@QuestionType", qt.name); cmd.Parameters.AddWithValue("@Limit", qt.numOfType);
2. DataReader跳过了第一条数据
你在while (dr.Read())循环之前,单独调用了一次dr.Read();——这会让DataReader直接跳到第二条数据,第一条数据就被漏掉了!如果数据库里只有一条符合条件的数据,那QuestionList就会是空的,转出来的数组自然也是空的,你就会误以为转数组失败。
把那行单独的dr.Read();删掉,只保留while (dr.Read())循环就好。
三、修正后的完整代码示例
我把所有问题都修正了,还加了using语句来自动释放资源(避免内存泄漏):
public class Gene { public string question { get; set; } public string CLO { get; set; } public string type { get; set; } public Gene(string s, string t, string i) { this.question = s; this.type = t; this.CLO = i; } } // 初始化试题列表 List<Gene> QuestionList = new List<Gene>(); // 参数化SQL查询,安全又可靠 string sql = "select Question, CLO, Question_Type FROM QuestionBank WHERE Subject = @Subject AND chapter = @Chapter AND Question_Type = @QuestionType ORDER BY RAND() LIMIT @Limit"; using (SqlCommand cmd = new SqlCommand(sql, con)) { cmd.Parameters.AddWithValue("@Subject", sub); cmd.Parameters.AddWithValue("@Chapter", chapter); cmd.Parameters.AddWithValue("@QuestionType", qt.name); cmd.Parameters.AddWithValue("@Limit", qt.numOfType); con.Open(); // 用using包裹DataReader,自动释放资源 using (SqlDataReader dr = cmd.ExecuteReader()) { // 直接循环读取所有数据,没有多余的dr.Read() while (dr.Read()) { string ques = dr["Question"].ToString(); string questype = dr["Question_Type"].ToString(); string quesCLO = dr["CLO"].ToString(); QuestionList.Add(new Gene(ques, questype, quesCLO)); } } con.Close(); } // 现在转数组肯定没问题了! Gene[] geneArray = QuestionList.ToArray();
最后再提个小建议
如果还是遇到问题,一定要看具体的错误提示——是编译时的红色波浪线,还是运行时的异常信息?根据错误信息排查会更快哦。
内容的提问来源于stack exchange,提问作者Sondos

