Софтуерно Инженерство
Loading...
+ Нов въпрос
Hristo_Penchev avatar Hristo_Penchev 388 Точки

[Homework] OOP - Defining Classes - Problem {3} - PC Catalog - изчисляване на цената

Здравейте,

Боря се със задачата PC Catalog, но не мога да се оправя с изчисляването на цената на компютъра. Ето кода на класа:

http://pastebin.com/E0xz6fY9

Поради някаква причина ми връща нула. Явно не достъпва цените на компонентите както трябва. 
Ето и кода на останалите класове:


http://pastebin.com/rdLkgz5p

http://pastebin.com/EDgjG6j6

Тагове:
-1
C# OOP Basics
Filkolev avatar Filkolev 4428 Точки

На ред 76 не трябва ли да е this.price, вместо this.Price? Ти си в рамките на класа така или иначе.

Не разглеждах много подробно кода, че решавам други задачи в момента, но видях и някои излишни неща. Например, когато хвърляш exception в if-statement, не е нужно да слагаш else-ове. Хвърлянето на exception е като return, то прекратява изпълнението на метода.

Също, при проверките за null стойност, по-добре хвърляй ArgumentNullException, по-точно описва ситуацията.

Като принтираш детайлите за компонентите, сложи един спейс след двоеточието.

Последно, за цената бих ползвал decimal, не float, освен ако така не пише в условието де, че не съм го чел още.

Едит: Мисля, че разбрах проблема. Ти имаш алгоритъм, по който смяташ цената на компа, но викаш ли го някъде? В конструктора за компютър даваш само име и компоненти, но никъде не сетваш цената. Може би за всеки компонент ако викаш сетъра за цената на компа и добавяш цената на компонента ще стане.

0
27/12/2014 16:21:14
Filkolev avatar Filkolev 4428 Точки

С лека корекция на кода всичко тръгна както трябва (предполагам, че така трябва да е). В конструктора сложих да се сетва цената на компа, самото пресмятане на цената го правя метод и го викам. 

Ето кодът - ЦЪК.

1
Hristo_Penchev avatar Hristo_Penchev 388 Точки

Така стана, но не съм сигурен, че разбирам защо. Явно трябва да мине през конструктора. Бях останал с впечатление, че конструкторът се ползва само за елементите, които се вкарват външно при създаване на нов обект.

0
RoYaL avatar RoYaL SoftUni Team Trainer 6883 Точки

Конструкторът е иницализационен метод, който се тригерва веднъж при създаване на обекта с "new". В него можеш/трябва да вкарваш логиката, която ти е нужна, за да ти работи класа след инициализирането му.

Представи си, че все дено вместо констуктор, имаш метод който се казва, да речем, Init() (даже май така се казваха в пайтън конструкторите?).

Засместваме конструктора със следния метод:

    public void Init(string name, List<Component> components)
    {
        this.Name = name;
        this.Components = components;
        this.Price = CalcPrice(components);
    }
 
И ето, съвсем нормален метод, който трябва ръчно да извикаш, за да започне обекта от тип компютър да работи нормално.

Computer computer = new Computer;

computer.Init(name, components);

@Filkolev добра практика е да се вика пропъртито, дори и да си в класа. Гетърите не винаги съответстват на полето. В повечето случаи имаш пропърти, на което get-а казва return this.field, но това не винаги е така. Да речем, че някой записва в каталога ти цената в евро, обаче искаш когато оперираш над нея или когато я показваш на потребителя, тя за е във валутата, с която се оперира в неговата държава. Тогава сетъра ще сетва цената в евро, но гетъра ще проверява какъв е локейла на потребителя и ще умножи по курса на съответната валута. Дори и да си вътре в класа, ти искаш да сметнеш цената на всички компонненти примерно в левове, въпреки че са вкарани в евро.
Тогава се намесва гетъра, който връща стойността според локейла и ти трябва да викнеш пропъртито, за да се тригерне гетъра. Разбира се debateful е това дали гетъра трябва да връща цена според локейла, може би примерът ми не беше много добър, но се надявам, че схващаш логиката. В езици като Джава и РНР е прието дори и в класа да се вика this.getPrice()http://stackoverflow.com/questions/271318/should-you-access-a-variable-within-the-same-class-via-a-property

1
27/12/2014 21:20:06
atanasovam avatar atanasovam 39 Точки

Добре де, без user input няма ли да стане? (без Console.ReadLine, всичко да си се пише в .cs файла)

Цял ден си играя с тая задача и не мога да я наглася... стигнах донякъде, ама е мн дървена и вади stack overflow exception

Components.cs

Computer.cs

PcCatalog.cs

Може ли малко помощ, трябва да има някакъв по-интелигентен метод от моя

1
Filkolev avatar Filkolev 4428 Точки

Аз съм си я направил без вход от потребителя. Кажи по-подробно къде какво дава overflow.

2
velio84 avatar velio84 241 Точки

Здрасти,

stackoverflow exception-a можеш да го хванеш с дебъгера. Пони отначало и като изгърми ще ти каже :)
Няколко други неща ми правят впечатление:

Mетодите public string DisplayComponents() и public string DisplayComputer() са ти излишни. Вместо тях пишеш

public override string ToString()

и в него връщаш някакъв стринг - това override-va името-на-обекта.ToString();

Т.е., ако имаш Component hdd; и му дадеш Console.WriteLine(hdd) -> това ще върне стойността, която си дал в override ToString()

След като оправиш компонента да връща стойността с пропертитата на обекта, като правиш override-a на Computer, не е нужно да ги пишеш пак 1 по 1 нещата - вече ги имаш. Като пример от твоя код, пишеш само:

if (this.GraphicsCard != null)

{ output += this.GraphicsCard.ToString(); }

За общата цена на компютъра - трябва да обходиш всички компоненти и да им вземеш .Price
Това става накрая най-лесно, като си оправиш останалите проблеми с exception-ите по задачата, ще го направиш лесно.

2
24/01/2015 00:13:30
AleksandurSeferinkin avatar AleksandurSeferinkin 335 Точки

В set-ъра на пропъртито Price в класа Computer го викаш рекурсивно.

this.Price = price; - Така пропъртито се вика само и се получава безкрайна рекурсия - StackOverFlowException

Също така в C# има елегантен, бърз и удобен начин да съединяваш стрингове - StringBuilder

1
24/01/2015 02:26:51