Вопрос № 164484: Здравствуйте уважаемые эксперты у меня вопрос по С# Создать класс студент (виртуальный) метод PassExam() возвращает оценку и 5 наследников, каждый со своей рареализацией. создать случайным образом коллекцию из 20 студентов. Вывести на кон...
Вопрос № 164.484
Здравствуйте уважаемые эксперты у меня вопрос по С#
Создать класс студент (виртуальный) метод PassExam() возвращает оценку и 5 наследников, каждый со своей рареализацией. создать случайным образом коллекцию из 20 студентов. Вывести на консоль распределение оценок и % списывавших.
Я думаю, что это должно выглядеть вот так, но работает неправильно. извиняюсь если помести не туда.
Приложение:
Отправлен: 08.04.2009, 23:16
Вопрос задал: Sky-er (статус: Посетитель)
Всего ответов: 1 Мини-форум вопроса >>> (сообщений: 6)
Отвечает: Micren
Здравствуйте, Sky-er! Честно говоря, задача поставлена так, что и решать ее не хочется в этом виде. Поэтому я ее немного усложнил. Предположим, что нашему коду заранее неизвестно количество потомков от Student. Вы можете создать любое их количество в сборке. Назвать их любыми именами(у меня названы St1..St5, но это не имеет значения). При этом остальной код можно не трогать. Благодаря применению рефлексии код сам извлечет информацию о потомках и создаст требуемый массив наследников. Единственное условие:
необходимо, чтоб наследник содержал конструктор с прототипом (string,uint).
using System; using System.Collections.Generic; using System.Reflection;
namespace DemoReflection { class Program { const uint studentsCount = 20; static void Main(string[] args) { try { // Создадим генератор случайных чисел Random rand = new Random(); // Список с информацией о конструкторах для потомков
Student List<ConstructorInfo> childConstructors = new List<ConstructorInfo>(); // Требуемый конструктор с параметрами (string,uint) Type[] constructorRequired = new Type[] { typeof(string), typeof(uint) }; // Пройдем по всем типам содержащимся в сборке foreach (Type t in Assembly.GetExecutingAssembly().GetTypes()) { //
Если найденный тип является классом if (t.IsClass) { // Если базовый тип у класса Student if (t.BaseType == typeof(Student)) { // Ищем в классе требуемый нам конструктор ConstructorInfo constructor = t.GetConstructor(constructorRequired); // Если такой конструктор найден добавим его в список
if (constructor != null) childConstructors.Add(constructor); } } } // А это наш массив студентов Student[] students = new Student[studentsCount]; // Пройдем по нему и заполним его потомками класса Student for (int i = 0; i < students.Length; ++i) { // Пар
аметры передаваемые конструктору // Имя Student+номер и случайная оценка от 2 до 5 object[] parameters = new object[2] { "Student " + i.ToString(), (uint)rand.Next(4) + 2 }; // Создаем объект и приводим его к родительскому типу Student students[i] = childConstructors[rand.Next(childConstructors.Count)].Invoke(parameters) as Student; } // В этом словаре будем хранить оценки
и их количество SortedDictionary<uint, uint> rateDict = new SortedDictionary<uint, uint>(); uint writtenOff = 0; // Количество списавших // Выводим наш массив студентов и считаем оценки и списавших Console.WriteLine("Студенты:"); foreach (Student s in students) { // Выводим инфо о студенте с указанием имени кл
асса для интереса(измените если не надо) Console.WriteLine("Тип:{0}, {1}", s.GetType().Name, s); uint rate; // Проверяем не списал ли студент и увеличиваем счетчик если так if (s.PassExam(out rate)) ++writtenOff; // Если наш словарь счетчиков оценок не содержит еще такую то добавим ее if (!rateDict.ContainsKey(rate)) rateDict.Add(rate, 0);
// Увеличим счетчик оценок ++rateDict[rate]; } // Выводим результат Console.WriteLine("Получено оценок:"); foreach (uint rate in rateDict.Keys) { Console.WriteLine("Оценка: {0}, Количество: {1}", rate.ToString(), rateDict[rate].ToString()); } Console.WriteLine("Списано:{0
}%", (double)writtenOff / students.Length * 100); } catch (System.Exception ex) { Console.WriteLine("Исключение: " + ex.Message); } finally { Console.ReadKey(); } } } // Классы потомки от Student class St1 : Student { public St1(string name, uint rate) : base(name, rate) { }
public override bool PassExam(out uint rate) { rate = this.rate; return true; } } class St2 : Student { public St2(string name, uint rate) : base(name, rate) { } public override bool PassExam(out uint rate) { rate = this.rate; return false; } } class St3 : Student {
public St3(string name, uint rate) : base(name, rate) { } public override bool PassExam(out uint rate) { rate = this.rate; return false; } } class St4 : Student { public St4(string name, uint rate) : base(name, rate) { } public override bool PassExam(out uint rate) { rate = this.rate; return false;
} } class St5 : Student { public St5(string name, uint rate) : base(name, rate) { } public override bool PassExam(out uint rate) { rate = this.rate; return true; } } // Класс Student abstract class Student { // Конструктор public Student(string name, uint rate) { this.name = na
me; this.rate = rate; } // абстрактный метод public abstract bool PassExam(out uint rate); // Имя private string name; public string Name { get { return name; } } // Оценка protected uint rate; public override string ToString() { return String.Format("Имя: {0}, Оценка: {1}", name, rate); } } }
* Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи.
(полный список тарифов)
** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются.
*** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании.