我有一个IEnumerable,我需要从中获取每个项目并逐个显示。显示不是一个连续的过程..即我应该获取一个项目并在UI上显示它,然后等待该项目的一些用户反馈,然后转到下一个项目。例如,从下面的代码中,我需要获取一个问题,然后将其显示给用户,然后用户点击进入,然后我继续提取下一个问题。
我的问题是我该怎么做? IEnumerable是实现此目的的最佳方式,还是应该恢复列表并开始存储索引并逐个递增?
请注意我使用的是.NET 3.5。
代码:
class Program
{
static void Main(string[] args)
{
Exam exam1 = new Exam()
{
Questions = new List<Question>
{
new Question("question1"),
new Question("question2"),
new Question("question3")
}
};
var wizardStepService = new WizardStepService(exam1);
var question = wizardStepService.GetNextQuestion();
//Should output question1
Console.WriteLine(question.Content);
Console.ReadLine();
//Should output question2 but outputs question1
question = wizardStepService.GetNextQuestion();
Console.WriteLine(question.Content);
Console.ReadLine();
//Should output question3 but outputs question1
question = wizardStepService.GetNextQuestion();
Console.WriteLine(question.Content);
Console.ReadLine();
}
}
public class Question
{
private readonly string _text;
public Question(string text)
{
_text = text;
}
public string Content { get { return _text; } }
}
internal class Exam
{
public IEnumerable<Question> Questions { get; set; }
}
internal class WizardStepService
{
private readonly Exam _exam;
public WizardStepService(Exam exam)
{
_exam = exam;
}
public Question GetNextQuestion()
{
foreach (var question in _exam.Questions)
{
//This always returns the first item.How do I navigate to next
//item when GetNextQuestion is called the second time?
return question;
}
//should have a return type hence this or else not required.
return null;
}
}
答案 0 :(得分:4)
是的,GetEnumerator()
应该可以正常工作;虽然严格来说你需要处理Dispose()
:
internal class WizardStepService : IDisposable
{
private IEnumerator<Question> _questions;
public WizardStepService(Exam exam)
{
_questions = exam.Questions.GetEnumerator();
}
public void Dispose()
{
if (_questions != null) _questions.Dispose();
}
public Question GetNextQuestion()
{
if (_questions != null)
{
if (_questions.MoveNext())
{
return _questions.Current;
}
Dispose(); // no more questions!
}
//should have a return type hence this or else not required.
return null;
}
}
还有:
using (var wizardStepService = new WizardStepService(exam1))
{
var question = wizardStepService.GetNextQuestion();
//Should output question1
Console.WriteLine(question.Content);
Console.ReadLine();
//Should output question2 but outputs question1
question = wizardStepService.GetNextQuestion();
Console.WriteLine(question.Content);
Console.ReadLine();
//Should output question3 but outputs question1
question = wizardStepService.GetNextQuestion();
Console.WriteLine(question.Content);
Console.ReadLine();
}
但是,由于您实际上并未每次都对结果进行测试,因此您还可以执行以下操作:
using (var questions = exam1.Questions.GetEnumerator())
{
questions.MoveNext();
var question = questions.Current;
//Should output question1
Console.WriteLine(question.Content);
Console.ReadLine();
//Should output question2 but outputs question1
questions.MoveNext();
question = questions.Current;
Console.WriteLine(question.Content);
Console.ReadLine();
//Should output question3 but outputs question1
questions.MoveNext();
question = questions.Current;
Console.WriteLine(question.Content);
Console.ReadLine();
}
或者作为最后的想法,也许只是:
var questions = exam1.Questions.Take(3).ToArray();
//Should output question1
Console.WriteLine(questions[0].Content);
Console.ReadLine();
//Should output question2 but outputs question1
Console.WriteLine(questions[1].Content);
Console.ReadLine();
//Should output question3 but outputs question1
Console.WriteLine(questions[2].Content);
Console.ReadLine();
答案 1 :(得分:3)
您可以存储IEnumerator<T>
,然后将GetNextQuestion
更改为:
return _exam.MoveNext() ? _exam.Current : null;
但是,此时您实际上并未使用Exam
或WizardStepService
类添加任何值,您也可以直接在IEnumerator<T>
中使用Main
。请注意,您的Main
方法本身有点奇怪 - 它重复了代码,其中foreach
循环会更简单 - 而且您无条件地提出三个问题。
请注意,如果你有一个IEnumerator<T>
类型的字段作为字段,你可能想要实现IDisposable
以便处理迭代器 - 这一切都有点混乱。
答案 2 :(得分:0)
试试这个:
class Program2
{
static void Main(string[] args)
{
Exam exam1 = new Exam()
{
Questions = new List<Question>
{
new Question("question1"),
new Question("question2"),
new Question("question3")
}
};
var wizardStepService = new WizardStepService(exam1);
foreach (var question in wizardStepService.GetQuestions())
{
Console.WriteLine(question.Content);
Console.ReadLine();
}
}
}
public class Question
{
private readonly string _text;
public Question(string text)
{
_text = text;
}
public string Content
{
get
{
return _text;
}
}
}
internal class Exam
{
public IEnumerable<Question> Questions
{
get;
set;
}
}
internal class WizardStepService
{
private readonly Exam _exam;
public WizardStepService(Exam exam)
{
_exam = exam;
}
public IEnumerable<Question> GetQuestions()
{
foreach (var question in _exam.Questions)
{
//This always returns the first item.How do I navigate to next
//item when GetNextQuestion is called the second time?
yield return question;
}
//should have a return type hence this or else not required.
//return null;
}
}