Професионална програма
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 6847 Точки
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 6847 Точки

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

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

Ами напротив, кодът ти не бачка :) Всмисъл ако е 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