Loading...
nick.genov avatar nick.genov 104 Точки

Дефиниране на класове - неработещ exception при грешни данни

Здравейте, колеги.

Опитвам се да възпроизведа един от примерите от лекцията за дефиниране на класове, водена от Светлин Наков. Примерът е между 22 и 25-та минута във видеото. Става дума за хвърляне на exception при въвеждане на данни за клас, които са извън допустимия обхват. Това е моят код: http://pastebin.com/kr6uCvWe 

Пробвах по различни начини (със и без конструктор), внимателно гледах кода в лекцията и се мъчих да видя разлика, дебъгвах... Не успявам да видя защо при мен exception не излиза. Сигурно грешката ми е нещо идиотско, но никога не съм се занимавал с ООП. Дайте едно рамо :)

Весела Коледа!

Тагове:
0
C# OOP Basics 25/12/2014 13:40:02
RoYaL avatar RoYaL Trainer 6849 Точки
Best Answer

Здравей,

Представи си сетъра като един метод, който извършва това:

public void setX(int value)

{

    this.Xcoord = value;

}

 

За да направиш валидация преди сетването, трябва да провериш дали подаденото като аргумент value е извън рейнджа, а не Xcoord. В C# сетърите получават магическата променлива value от съответния тип, от какъвто е пропъртито, съответно трябва да проверяваш нея дали е в дадения рейндж.

    public int X

    {
        get
        {
            return this.xCoord;
        }
        set
        {
            if ((value < 0) || (value > 100))
            {
                throw new ArgumentOutOfRangeException("The value must be in the range [0..100]");
            }
            else
            {
                this.xCoord = value;
            }
        }
    }
 
Това, котео проверяваш ти е дали текущата стойност на полета е по-малка от 0 или по-голяма от 100. В твоя случай това ще изгърми втория път, когато веднъж сетнеш стойност по-голяма от 100, и след това се опиташ да сетнеш нова, ще провери че предишната стойност е по-голяма от 100и ще хвърли ексепшън. Идеята е да проверяваш дали подадения от потребителя аргумент е извън рейнджа.
2
Gleomit avatar Gleomit 29 Точки

Първата ти проверка винаги няма да бачка, защото в класа "Point" default стойности не си сложил и един вид са NULL(предполагам, може и да греша). ако се пробваш на същия обект да сетнеш отново отрицателна стойност тогава ще работи и ще хвърли exception. Това е малък едит на твоя код: http://pastebin.com/SufYpRbp :)

0
RoYaL avatar RoYaL Trainer 6849 Точки

Ако се пробва на същия обект да сложи каквато и да е стойност ще изгърми, ако първият път е сложли невалидна

        Point p1 = new Point(1000, -1000);
        p1.X = 10;

Ще изгърми на 2рия ред :)

Дефолтната стойностите на INT са 0. Проблемът е, че се опитвате да проверявате предишната стойност, а не подадената в момента.

         this.yCoord = value;
         if ((yCoord < 0) || (yCoord > 100))
         {

           throw new ArgumentOutOfRangeException("The value must be in the range [0..100]");
         }

Това, което си написал няма огромен смисъл. Да, ще хвърли ексепшън, но първо ще сложи стойността :)

 

1
25/12/2014 13:58:49
Gleomit avatar Gleomit 29 Точки

Не е най - правилното решение, така е, просто това ми дойде на ума : )

0
25/12/2014 14:02:08
RoYaL avatar RoYaL Trainer 6849 Точки

Ами напротив, кодът ти не бачка :) Всмисъл ако е 1 към 1 както си го написал, ще работи, но има side-effects.

Ти първо слагаш xCoord = value а после хвърляш ексепшън. Т.е. първо ще асайнне стойността и после ще прекрати зипълнението на програмата.

Ако обаче бъде оградено в try {} catch блок, изпълнението няма да се прекрати и познай какво ще стане от този код:

        public static void Main()
    {
        Point p1 = new Point();

        try {
            p1.X = 1000;
        } catch (Exception e) {
        }

        try {
            p1.Y = -1000;
        } catch (Exception e) {
        }

        Console.WriteLine(p1.X);
        Console.WriteLine(p1.Y);
    }

Ще изведе на конзолата:

1000

-1000

 

 

 

1
nick.genov avatar nick.genov 104 Точки

Благодаря!

 

Промених проверките да са с value и проработи. Все още не съм разгадал как при Наков работеше, проверявайки x (а не value), но ще успея :)

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