我希望创建一个在线测验,可以从成千上万的程序问题中提出任何问题。每个问题都是通过一个函数创建的,该函数给出一个int数组,其值确定显示的确切问题。我把每个问题都作为一个班级:
public class AddingTwoDigitNumbers : IQuestion
{
public string QName() { return "Adding Two-Digit Numbers" };
public int[] QParams() { return int[]() {Random(10, 99), Random(10, 99) };
public void Question(int[] values) {
Console.WriteLine(string.Format("What is {1} + {2}?", values[0], values[1]);
}
public void Answer(int[] values) {
Console.WriteLine(values[0] + values[1]).ToString());
}
}
QParams
创建int数组(以确定所创建的问题),同时提供给Question
和Answer
以创建问题和答案。
我希望List
可以搜索QName
个问题,但不想创建(并命名)数千个实现IQuestion
的类。
所以这是我的第二个解决方案:
public class Question
{
public string QName { get; set; }
public Func<int[]> QParams { get; set; }
public Action<int[]> Question { get; set; }
public Action<int[]> Answer { get; set; }
}
public class QuestionRepository
{
public static Dictionary<string, Question> Questions = new Dictionary<string, Question>();
public static void AddQuestions(Question[] qs) {
foreach (Question q in qs) Questions.Add(q.QName, q);
}
}
public class FirstSetOfQuestions
{
static void AddQuestions()
{
QuestionRepository.AddQuestions(new Question[]
{
new Question()
{
QName = "Adding Two-Digit Numbers",
QParams = () => int[]() {Random(10, 99), Random(10, 99) },
Question = (v) => {Console.WriteLine(string.Format("What is {1} + {2}?", v[0], v[1]);},
Answer = (v) => {Console.WriteLine(values[0] + values[1]).ToString());}
},
new Question()
{
QName = "Subtracting Three-Digit Numbers",
QParams = () => int[]() {Random(100, 999), Random(100, 999) },
Question = (v) => {Console.WriteLine(string.Format("What is {1} - {2}?", v[0], v[1]);},
Answer = (v) => {Console.WriteLine(values[0] - values[1]).ToString());}
}
}
}
}
所以我的问题是哪个更好?我是否创建了数千个类,必须为每个类提供一个名称,或者我是否创建了数千个匿名函数以及使用(我假设)委托来存储这些函数的类?如果我有成千上万的问题,或者甚至是更好的方法,那么第二个解决方案是否存在问题?
(显然我想要创建的问题比这里显示的要复杂得多,涉及分数,代数等。)
答案 0 :(得分:3)
只是为了让你开始使用流利的语法,并在那里引入一些存根和想法。
class Question
{
public string Name { get; set; }
public string QuestionFormat { get; set; }
public List<Range> Args { get; set; }
public Expression<Func<int[], int>> ValExp { get; set; }
public Question(string name, string questionFormat)
{
this.Name = name;
this.QuestionFormat = questionFormat;
this.Args = new List<Range>();
}
public Question Rand(int min, int max)
{
this.Args.Add(new Range(min, max));
return this;
}
public void Val(Expression<Func<int[], int>> exp)
{
this.ValExp = exp;
}
public CompiledQuestion Compile()
{
// Generate args in the appropriate ranges
// Evaluate the result with the ValExp
// Return a new CompiledQuestion with the information -
// basically just replacing Args, ValExp with RealArgs, Val
}
public ICoolDataObject Save()
{
}
public static Question Load(ICoolDataObject hmm)
{
}
}
class Range
{
public int Min { get; set; }
public int Max { get; set; }
public Range(int min, int max)
{
this.Min = min;
this.Max = max;
}
}
这很有趣,现在就提出问题:
new Question("simple addition",
"whats {0} + {1}?")
.Rand(10, 99)
.Rand(10, 99)
.Val(v => v[0] + v[1]);
显然,您可以添加一些验证检查,以避免由于工作时间较晚而导致的参数数量不正确,并且无论何处使用double
或decimal
而不是int
。
答案 1 :(得分:2)
两种方法都是错误的。我认为你不会有数以千计的不同类型的计算。您只需要进行十几种或几十种不同类型的计算,对各种各样的数据进行操作。
因此,您需要对数据进行规范化,以便最终在明确定义的数据的数据库上进行大约十几个或几十个不同的明确定义的计算,最后写下十几个或几个类,一个用于各种计算,仅。
您可能认为这太复杂了,您可能会认为编写成千上万的课程(或代表,这并不重要)可能需要做很多工作,但每件作品都很小而且容易,但请相信我,你一旦某些东西需要在接口或所有这些类的实现上发生变化,就会非常遗憾地这样做,并且大多数机会都需要在某个时间点进行更改。