使用随机 c# 时,索引超出数组的边界



我创建了一个问题池,从中选择随机问题来应用一些算法,无论如何,当我调试程序时,我得到的索引超出了数组错误的范围。

为了清楚地了解我在说什么,这是我的问题:

首先我定义类基因代表问题

public class Gene
{
public string question { get; set; }
public string CLO { get; set; }
public string type { get; set; }
public string Answer { get; set; }
public string mark { get; set; }
public string chapter { get; set; }
public Gene(string s, string t, string i, string a, string m, string c)
{
this.question = s;
this.type = t;
this.CLO = i;
this.Answer = a;
this.mark = m;
this.chapter = c;
}
}
List<Gene> QuestionList = new List<Gene>();

然后我从数据库中提出问题

protected void DropDownList5_SelectedIndexChanged(object sender, EventArgs e)
{
string sub = DropDownList5.Text;

SqlConnection con = new SqlConnection(@"Data Source=.SQLEXPRESS;AttachDbFilename=C:UsersSondosDownloadsFor the projectsuzExamGenerationSystem.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True");
string s = "select * FROM QuestionBank WHERE (Cource_Code = '" + DropDownList5.SelectedItem.Text + "') ORDER BY RAND()";
SqlCommand cmd = new SqlCommand(s, con);
SqlDataReader dr;
con.Open();
dr = cmd.ExecuteReader();
dr.Read();
while (dr.Read())
{
string ques = dr["Question"].ToString();
string questype = dr["Question_Type"].ToString();
string quesCLO = dr["CLO"].ToString();
string quesAnswer = dr["Answer"].ToString();
string quesMark = dr["Mark"].ToString();
string quesChapter = dr["Chapter"].ToString();
QuestionList.Add(new Gene(ques, questype, quesCLO, quesAnswer, quesMark, quesChapter)); 
}
}

然后我提出问题池

Gene[] QuestionPool { get { return QuestionList.ToArray(); } }

当我尝试使用这个随机选择问题时:

private System.Random randome;
private Gene GetRandomQuestion()
{
int i = randome.Next(QuestionPool.Length);
return QuestionPool[i];
}

错误索引超出数组的边界 在行中

return QuestionPool[i];

int i = randome。下一个(问题池.长度);

在这里,如果QuestionPool为空,则变为返回零的int i = randome.Next(0)。 因此

返回 QuestionPool[i];//其中 i 变为 0

将抛出Index was outside the bounds,因为问题池为空,并且在索引 0 处没有任何内容。

因此,请确保问题池不为空。


一些会导致QuestionPool空的情况。

  1. 数据库中没有Cource_Code = DropDownList5.SelectedItem.Text的记录 在这种情况下,while (dr.Read())将在第一次迭代时false,并且不会向QuestionList添加任何Gene
  2. 在将任何Gene添加到QuestionList之前调用GetRandomQuestion

避免 SQL 注入

此行容易受到 SQL 注入的攻击

(Cource_Code = '" + 下拉列表5.选定项.文本 + "')

这意味着,如果用户将选定项的文本更改为类似

a'); Drop table QuestionBank; -- //Anything after -- becomes a comment

然后查询将变为

select * FROM QuestionBank WHERE (Cource_Code = 'a'); Drop table QuestionBank;

你的桌子将被丢弃。

为避免这种情况,请参阅此答案。


列表为数组

当您有列表时,您还可以按索引访问其项目。要获得其长度,您可以使用计数。 因此,GetRandomQuestion可以成为

private Gene GetRandomQuestion()
{
int i = randome.Next(QuestionList.Count);
return QuestionList[i];
}

而且您不需要 QuestionPool,前提是您仅将其用于此目的。

在引用它之前,您只是错过了实例化随机

private System.Random randome;
private Gene GetRandomQuestion()
{
randome = new System.Random  // here
int i = randome.Next(QuestionPool.Length);
return QuestionPool[i];
}

最新更新