Защо C# свързана променлива на клас от списък не запазва стойността си, след като е присвоена?

Създавам генератор на кръстословици и изглежда имам проблем с просто присвояване на променлива на координати в мрежовата система. Имам много проста структура за задържане на дискретни координатни стойности, както се вижда по-долу. Премахнах капсулирането, за да улесня четенето.

    public struct vec2
    {
        public int x, y;
        public vec2(int x, int y)
        {
            this.x = x;
            this.y = y;
        }
    }

Тази Vec2 структура се поддържа вътре в клас, за да съхранява стойности на думи

public struct WordClass
{
    string svalue;
    bool flag;
    public vec2 position;

    public WordClass(string sarg, bool barg)
    {
        this.svalue = sarg;
        this.flag = barg;
        position = new vec2(0,0);
    }
    public string StringVal
    {
        get { return svalue; }
    }
    public bool FlagVal
    {
        get { return flag; }
    }
    public void DisableWord()
    {
        if (this.flipflop == false)
        {
            this.flipflop = true;
        }
    }
    public void SetPos(int xa, int ya)
    {
        this.position.x = xa;
        this.position.y = ya;
    }
}

Това основно трябва да поддържа списък с постоянни думи с флаг за употреба и променлива позиция, тъй като системата изчислява оптималните местоположения за думата.

Имам динамичен свързан списък с думи

    List<WordClass> WordList = new List<WordClass>();

и за промяна на координатите на дума в списъка с думи

    //Arbitrary values
    WordList[0].SetPos(Position_X, Position_Y);

Сега проблемът ми е, че когато се опитвам да използвам позицията на думата, без значение какво съм я задал твърде преди, тя поддържа стойност по подразбиране от 0, 0. Чесах се по главата, докато изпълнявах друга функционалност, и това ме остави чудя се дали не пропускам нещо важно.


person Byren Higgin    schedule 27.09.2015    source източник
comment
Вижте Кога да използвате struct?. Вашите структури са променливи, което може да причини проблеми като този, когато се опитвате да зададете стойност, но тя не изглежда да се задържа, защото всъщност променяте стойността на копие на структурата. Не мисля, че трябва да използвате структури тук.   -  person 31eee384    schedule 27.09.2015
comment
Наздраве за връзката, все още съм любител програмист и мислех, че класовете и структурите са напълно взаимозаменяеми в c#. Това изглежда най-вече реши проблема ми.   -  person Byren Higgin    schedule 27.09.2015


Отговори (1)


Проблемът изглежда е свързан с факта, че vec2 е ValueObject и вие се опитвате да го промените. Проблемните редове са конкретно тези два:

this.position.x = xa;
this.position.y = ya;

Защо? Тъй като vec2 е struct всеки път, когато го четете, получавате временно копие, след което променяте това копие, след което копието се изхвърля, докато все още четете оригинала, непроменен. Това е една от причините стойностните обекти да бъдат неизменни колкото е възможно повече, освен ако нямате сериозна причина.

Първата стъпка трябва да бъде да се направи правилна неизменна vec2 структура:

public struct vec2
{
    public int x { get; private set; }
    public int y { get; private set; }

    public vec2(int x, int y)
    {
        this.x = x;
        this.y = y;
    }
}

След като го получите, трябва да се погрижите за модификацията в метода SetPos. Тъй като структурата е неизменна, вече не можете да я четете, но вместо това всеки път, когато трябва да я промените, ще изхвърлите текущия екземпляр и ще създадете нов:

public void SetPos(int xa, int ya)
{
    this.position = new vec2(xa, ya);
}

Това създава чисто нова структура и я свързва с вътрешното поле, съдържащо новите стойности. Тъй като това всъщност не се опитва да модифицира структурата, а вместо това променя структурата за нова, тя няма да бъде обект на същата фина грешка.

person Alejandro    schedule 27.09.2015
comment
vec2 е структура всеки път, когато го прочетете, получавате временно копие Сигурни ли сте, че това се случва в този конкретен случай? Обърнете внимание, че имаме List<WordClass> и WordClass също е struct. - person AlexD; 27.09.2015
comment
Наздраве за това, съчетано с коментара, направен по въпроса ми от @31eee384, това напълно реши проблема ми. Беше свързано с временни копия и структури. - person Byren Higgin; 27.09.2015
comment
@AlexD Това само ще изостри проблема, така че вместо това проблемът с временното копиране може да се случи два пъти. Не съм проверил толкова внимателно, колкото би трябвало, но все пак проблемът с променливите структури е налице. Въпреки това, когато имам компилатор под ръка, ще тествам :D - person Alejandro; 27.09.2015
comment
@Alejandro Ако имаме достъп до полето position както в дадения код, не трябва да се създава копие на структурата. - person AlexD; 27.09.2015