Один из способов сделать это - создать IQuestion
интерфейс, содержащий все методы и свойства publi c, необходимые для запуска теста:
public interface IQuestion
{
void AskQuestion();
string CorrectAnswer { get; }
bool IsCorrect { get; }
}
Затем вы можете получить коллекция этого интерфейса в вашем Quiz
классе:
public class Quiz
{
public ICollection<IQuestion> Questions { get; set; }
}
Теперь мы можем создать отдельные классы, каждый из которых реализует свойства и методы IQuestion
по-своему.
Например:
public class TextQuestion : IQuestion
{
public bool IsCorrect => string.Equals(_userAnswer?.Trim(), CorrectAnswer?.Trim(),
StringComparison.OrdinalIgnoreCase);
public string CorrectAnswer { get; }
private readonly string _question;
private string _userAnswer;
public TextQuestion(string question, string answer)
{
_question = question;
CorrectAnswer = answer;
}
public void AskQuestion()
{
Console.WriteLine(_question);
_userAnswer = Console.ReadLine();
}
}
public class MultipleChoiceQuestion : IQuestion
{
public bool IsCorrect => _userIndex == _correctIndex + 1;
public string CorrectAnswer => (_correctIndex + 1).ToString();
private readonly string _question;
private readonly List<string> _choices;
private readonly int _correctIndex;
private int _userIndex;
public MultipleChoiceQuestion(string question, List<string> choices, int correctIndex)
{
_question = question;
_choices = choices;
_correctIndex = correctIndex;
}
public void AskQuestion()
{
Console.WriteLine(_question);
for (var i = 0; i < _choices.Count; i++)
{
Console.WriteLine($"{i + 1}: {_choices[i]}");
}
_userIndex = GetIntFromUser($"Answer (1 - {_choices.Count}): ",
i => i > 0 && i <= _choices.Count);
}
private static int GetIntFromUser(string prompt, Func<int, bool> validator = null)
{
int result;
do
{
Console.Write(prompt);
} while (!int.TryParse(Console.ReadLine(), out result) &&
(validator == null || validator.Invoke(result)));
return result;
}
}
public class TrueOrFalseQuestion : IQuestion
{
public bool IsCorrect => _userAnswer == _correctAnswer;
public string CorrectAnswer => _correctAnswer.ToString();
private readonly string _question;
private readonly bool _correctAnswer;
private bool _userAnswer;
public TrueOrFalseQuestion(string question, bool correctAnswer)
{
_question = question;
_correctAnswer = correctAnswer;
}
public void AskQuestion()
{
_userAnswer = GetBoolFromUser(_question + " (true/false)");
}
private static bool GetBoolFromUser(string prompt)
{
bool result;
do
{
Console.Write(prompt + ": ");
} while (!bool.TryParse(Console.ReadLine(), out result));
return result;
}
}
Пример использования
static void Main()
{
var quiz = new Quiz
{
Questions = new List<IQuestion>
{
new MultipleChoiceQuestion("Which color is also a fruit?",
new List<string> {"Orange", "Yellow", "Green"}, 0),
new TextQuestion("What is the last name of our first president?",
"Washington"),
new TrueOrFalseQuestion("The day after yesterday is tomorrow", false),
}
};
foreach (var question in quiz.Questions)
{
question.AskQuestion();
Console.WriteLine(question.IsCorrect
? "Correct!\n"
: $"The correct answer is: {question.CorrectAnswer}\n");
}
Console.WriteLine("Your final score is: " +
$"{quiz.Questions.Count(q => q.IsCorrect)}/{quiz.Questions.Count}");
GetKeyFromUser("\nPress any key to exit...");
}