Связанные свойства: как избежать бесконечного цикла

#c# #infinite-loop

#c# #бесконечный цикл

Вопрос:

У меня есть класс Cube. Куб может быть ограничен так, чтобы width=height=length . Я закодировал эту функциональность, но, как вы можете видеть, мой код приводит к циклическому / бесконечному циклу — the width sets the height which sets the width which sets the height and so on .

Как я могу ограничить свой класс куба и избежать этого бесконечного цикла? Является ли моим единственным решением использовать логическую переменную propagate (см. Ниже)?

 public class Cube {

    public bool isConstrained {get; set;} // if constrained then width=height=length

    // Causes a circular problem. How can I avoid this? Maybe create a variable private bool propagate = false; ??
    public double width
    {
        get { return width;  } 
        set 
        { 
            width  = value; 
            if (isConstrained) 
            {
                 height = value;
                 length = value; 
            }  
        } 
    }

    public double height
    { 
        get { return height;  } 
        set 
        {   
             height  = value; 
             if (isConstrained) 
             { 
                 width = value;
                 length = value; 
             } 
        } 
    }

    public double length
    {
         get { return length;  }
         set
         { 
              length  = value;  
              if (isConstrained) 
              { 
                  height = value; 
                  width = value; 
              } 
         } 
    }
}
  

Мое единственное решение таково:

 private bool propagate = true;

public double length
{
    get { return length;  } 
    set 
    {
         length  = value; 
         if (isConstrained amp;amp; propagate) 
         { 
             propagate = false;
             height = value; 
             width = value; 
             propagate = true;
         }
    }
}
  

Комментарии:

1. Почему не частные поля?

2. @Mephy Я не совсем понимаю, как это решит мою проблему? Моя цель состоит в том, чтобы люди могли устанавливать свойства кубов извне (общедоступно), но когда куб ограничен, и я устанавливаю ширину, я хочу, чтобы высота и длина также менялись (на значение ширины).

Ответ №1:

В настоящее время даже только ваши методы получения приведут к переполнению стека — у вас нет полей, поддерживающих ваши данные, потому что вы не используете автоматически реализованные свойства. Кроме того, ваши свойства не имеют обычных имен, что определенно стоит исправить.

Вы должны просто использовать закрытые поля для резервного копирования свойств и соответствующим образом устанавливать их в своих установщиках свойств. Таким образом, ни одно свойство не будет вызывать другое, и все будет хорошо… за исключением того, что дизайн был немного хлопотным для начала. (Когда изменение одного свойства изменяет другое, это может быть удивительно.)

Итак, что-то вроде:

 private int width;
private int height;
private int length;
private bool constrained;
...

public int Width
{
    get { return width; }
    set
    {
        width = value;
        if (constrained)
        {
            height = value;
            length = value;
        }
    }
}
  

Комментарии:

1. это хорошее решение, я надеялся, что есть более элегантный способ его решения — потому что это решение включает в себя 2 ‘переменные / свойства’ для ширины, для высоты, для длины, для и т.д.

2. @MillieSmith lol да, куб должен, но опять же мне понадобится другой класс для polygon. Таким образом, у меня может быть 1 класс a Cube (я должен переименовать его в Polygon ), который может быть либо кубом, либо полигоном

3. Полигон — это 2d, а куб — 3d. Вы не хотите использовать один и тот же класс для их представления.. Я бы даже не стал расширять одно из другого

4. @JakeM: для каждого значения используется одна переменная и одно свойство. Для меня это имеет смысл. Каким образом что-нибудь было бы более элегантным? Вы понимаете, что даже без использования constrained ваш текущий код просто сломан? Вам может сойти с рук только одно объявление свойства для комбинации переменной и свойства, если вы используете автоматически реализуемые переменные.

Ответ №2:

Разве длина, ширина и высота куба не должны всегда быть одинаковыми? Вы можете использовать одну закрытую переменную для хранения длины, ширины и высоты, а затем при настройке любого из этих свойств присваивать это значение закрытой переменной. Верните значение той же переменной в свойствах get для width / height / length .