[OOP] Fundamental Principles Part I - Задача 2


13
Условие:

Define abstract class Human with first name and last name. Define new class Student which is derived from Human and has new field – grade. Define class Worker derived from Human with new property WeekSalary and WorkHoursPerDay and method MoneyPerHour() that returns money earned by hour by the worker. Define the proper constructors and properties for this hierarchy. Initialize a list of 10 students and sort them by grade in ascending order (use LINQ or OrderBy() extension method). Initialize a list of 10 workers and sort them by money per hour in descending order. Merge the lists and sort them by first name and last name.

Решение:  GitHub

Обяснение: Клас Human е базов за Student и Worker.

Обединяване на двата обекта var mergedlists = workers.Concat<Human>(students).ToList();

и след това сортиране
             mergedlists = mergedlists.OrderBy(list => list.FirstName).ThenBy(list=> list.LastName).ToList();

Обновено според новите условия

Екип модератори - тагове


в C# OOP от ipenev (1013 точки)


Отговори



1

Решение: цък

Имам абстрактен клас Human, който е базов за Student и Worker. С един рандом генерирам малко различни параметри. Имената на хората съм ги направил супер тъпи но за примера стават :). Сортирането извършвам с OrderBy и OrderByDescending. Двата листа ги сливам в един, от тип Human с помощта на AddRange на лист-а. За сортирането може може да се използва LINQ или директно сорт метода на листа, защото съм имплементирал IComparable в Human.


от stanchev (197 точки)


1
Ще си позволя да вдигна старата тема, тъй като въпросът ми е по същата задача.
Някой може ли да ми обясни защо всички правят сортиранията в Main-метода? Имаме 3 подобни сортирания на подобни обекти и абстрактен клас. Абстрактният клас ако има само полета и конструктори, въобще не е абстрактен, а LINQ учихме по-рано и надали идеята е да си го упражним в Main().
Според мен трябва да се дефинира абстрактен метод в Human, който да се имплементира в Student и в Worker, а за общото сортиране може да се използва някак си дефинираното в Human или да се имплементира по трети начин. На теория добре, но въобще не можах да го направя на практика... Имате ли идеи как може да стане това?



0
Ами просто не е нормално човек/студент да може да сортира хора/студенти.Сортировката трябва да е в main-а, или в някой друг метод, който да приема колекция от human/student/worker обекти и да ги сортира по даден критерий.



0

Една приятно лесна задачка :) В класовете Student и Worker съм включил по 1 метод, който създава списък от определен брой студенти или работници(зависи за кой клас говорим) с рандом детайли за по-лесно тестване.

https://github.com/huuuskyyy/CSharp-Homeworks/tree/master/OOP%20Principles%20-%20I/02.%20Human


от Vazzzz (1380 точки)


0

GitHub

Правя override na ToString още при human за да ги стрингосвам по-късно по-лесно.

По интересното тук е обединението на двата листа - аз го реализирам с List<Human> и после AddRange от двата листа.


от dzhenko (3893 точки)


1

http://git.io/J2PNew

За мен най-интересното в задачата беше, че може да се ползва екстешън методът .Concat<T> за да се слеят двата наследника на Human в Enumerable<Human>. Подозирам, че това ще е удобно в доста  случаи, когато е по-удобно да се ползва полиморфизъм.


от georgiwe (720 точки)


0
Аз просто ги напъхах в един List

от scarylabcat (801 точки)

0
И аз първо за това се сетих, но реших че не може да няма по-добър начин и порових в гугъл.

от georgiwe (720 точки)


0

Aз съм позлвал IEnumerable<Student> и така не се налага да прехвърлям към List или Array, направо работя с интерфейса. Освен това си генерирам случайни студенти и работници :) За целта съм си направил един статичен клас, който ми дава случайни английски имена.

Ето решението: GitHub


от neutrino (3376 точки)


1

Ето и моето решение. За по-готино съм пренаписал ToString() още в базовия клас Human, а после в наследниците Student и Worker само го топълвам. Събирането на Student и Worker го правя в общ списък от Human. След това ги подреждам по имена.


от dimo.petrof (2887 точки)


1
Това е моят вариант, сложих един таймер и според него AddRange е доста по-бързо от Concat.

https://github.com/vasilev81/ForthHomeWorkOOPPartTwo

от topsoft (420 точки)


0
Ами не съм сигурен, че трябва да има голяма разлика между двете, въпреки, че Concat не променя първоначалните колекции, а създава нова, като при това трябва да обходи всички елементи и на двете. AddRange от своя страна не създава нова колекция, а променя текущата, като към нея добавя новите елементи. Според мен забавянето идва защото извикваш ToList() при Concat, което отнема немалко време (мисля, че отново обхожда IEnumerable колекцията и я превръща в List). EDIT: Току що тествах и ако махнеш ToList ще видиш доста драматично подобрение :-)

от gallumbits (2371 точки)

0
Възможно е, реших да пробвам , защото прочетох някъде, че е по бавно....

от topsoft (420 точки)


1
Здравейте, след като приключих с домашното по тази тема, дойде ми на ум, че за обединяването на студенти и работници, ако се използва LINQ (както е по условие), би трябвало да се използва метод, подобен на оператора Union в SQL.
Потърсих в Google и намерих метода Enumerable.Union. Използвах го, като каствах students към IEnumerable

от ellapt (6303 точки)