Loading...
Hristo_Penchev avatar Hristo_Penchev 389 Точки

[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 4482 Точки

На ред 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 4482 Точки

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

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

1
Hristo_Penchev avatar Hristo_Penchev 389 Точки

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

0
RoYaL avatar RoYaL Trainer 6849 Точки

Конструкторът е иницализационен метод, който се тригерва веднъж при създаване на обекта с "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 4482 Точки

Аз съм си я направил без вход от потребителя. Кажи по-подробно къде какво дава 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 333 Точки

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

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

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

1
24/01/2015 02:26:51
Можем ли да използваме бисквитки?
Ние използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Можете да се съгласите с всички или част от тях.
Назад
Функционални
Използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Използваме „сесийни“ бисквитки, за да Ви идентифицираме временно. Те се пазят само по време на активната употреба на услугите ни. След излизане от приложението, затваряне на браузъра или мобилното устройство, данните се трият. Използваме бисквитки, за да предоставим опцията „Запомни Ме“, която Ви позволява да използвате нашите услуги без да предоставяте потребителско име и парола. Допълнително е възможно да използваме бисквитки за да съхраняваме различни малки настройки, като избор на езика, позиции на менюта и персонализирано съдържание. Използваме бисквитки и за измерване на маркетинговите ни усилия.
Рекламни
Използваме бисквитки, за да измерваме маркетинг ефективността ни, броене на посещения, както и за проследяването дали дадено електронно писмо е било отворено.