C # Изменение возврата пользовательского типа данных во время выполнения - PullRequest
1 голос
/ 14 февраля 2012

Я учил себя C #, и я только учусь, как использовать пользовательские типы данных. Программа, которую я пишу, производит несколько пар координатных пар. Я подумал, что было бы неплохо создать тип данных, содержащий каждый набор (x1, x2, y1, y2), а также несколько других переменных, относящихся к этому набору. Тем не менее, программа будет генерировать более одного массива наборов координат (разных категорий), поэтому отслеживать вещи по-прежнему сложно. Затем я разбил его далее на категории и поместил каждую категорию в третий тип, который действует как третий уровень, который затем помещается в список.

Каждый «уровень» элементов имеет некоторые свойства, характерные для этого уровня, но до этого препятствия у меня не было необходимости обмениваться данными в иерархии. Проблема возникла, когда я понял, что мне нужно изменить наборы пар координат, используя смещение, и каждое смещение зависит от родительского типа данных. Я могу изменить код get {} так, чтобы он возвращал данные плюс смещение (я назвал это «перекосом»), но не в том случае, если смещение находится за пределами самого класса типа данных. Я попытался установить значение в родительском типе данных (даже в общедоступном статическом), но ребенок по какой-то причине не смог его прочитать.

Единственный способ, которым я знаю, как сделать эту работу, - установить свойство в каждом наборе координат, но их может быть тысячи. Значение является уникальным для родителя, но все дети должны использовать его, так что это кажется расточительным, учитывая, что будет много других вычислений. Моя другая мысль состояла в том, чтобы сохранить массив смещений и добавить его в места, где получены значения. Но это не так чисто, как содержать его внутри самого типа данных, и поэтому это приведет к путанице. Есть ли другой способ сделать это?

Вот как выглядит код:

public class SlotData
    {
        private double _x1, _x2, _y1, _y2;

        public double X1
        {
            get { return _x1; }
            set { _x1 = value; }
        }
        public double X2
        {
            get { return _x2; }
            set { _x2 = value; }
        }
        public double Y1
        {
            get { return _y1; }
            set { _y1 = value; }
        }
        public double Y2
        {
            get { return _y2; }
            set { _y2 = value; }
        }
    }
public class ClientInfo
    {
        public static double _skewX, _skewY;

        public SlotGroup1 Group1
        {
            get;
            set;
        }
        public SlotGroup2 Group2
        {
            get;
            set;
        }
        public SlotGroup3 Group3
        {
            get;
            set;
        }
    }

public class SlotGroup1
    {
        public SlotData Slot1
        {
            get;
            set;
        }
        public SlotData Slot2
        {
            get;
            set;
        }
    }

Ответы [ 2 ]

1 голос
/ 14 февраля 2012
    public class SlotData
    {
        private SlotData() { }
        public SlotData(SlotGroupBase group) 
        {
            this._group = group;
        }

        private SlotGroupBase _group;

        public double X1 { get; set; }
        public double X2 {get; set;}
        public double Y1 {get; set;}
        public double Y2 {get; set;}

        public double NewX1 
        {
            get
            {
                return _group.ClientInfo._skewX + X1;
            }
        }
    }

    public class ClientInfo
    {
        public double _skewX, _skewY;

        public SlotGroup1 Group1 { get; set; }
    }

    public abstract class SlotGroupBase
    {
        private SlotGroupBase() { }
        public SlotGroupBase(ClientInfo ci) 
        {
            this._ci = ci;
        }

        private ClientInfo _ci;

        public ClientInfo ClientInfo
        {
            get
            {
                return _ci;
            }
        }            
    }

    public class SlotGroup1 : SlotGroupBase
    {
        public SlotGroup1(ClientInfo ci):base (ci) {}
        public SlotData Slot1 { get; set; }
        public SlotData Slot2 { get; set; }
    }

    static void Main(string[] args)
    {
        ClientInfo ci = new ClientInfo();
        SlotGroup1 sg1 = new SlotGroup1(ci);
        sg1.Slot1 = new SlotData(sg1);
        sg1.Slot2 = new SlotData(sg1);
        Console.ReadLine();
    }

В вашем коде нет родительских или дочерних типов данных. Таким образом, члены какого-либо типа не могут быть доступны для других типов никоим образом, кроме как у вас будет ссылка на экземпляр объекта какого-либо типа.

Но объектно-ориентированное программирование может вам помочь. В случае, если каждый из типов SlotGroupN должен иметь ссылку на ClientInfo, было бы целесообразно иметь базовый класс SlotGroupBase, который будет содержать ссылку на ClientInfo. Также вы должны добавить к SlotData ссылку на тип SlotGroupBase. В этом случае вы получите доступ к вашим перекосам, таким как

return _group.ClientInfo._skewX + X1;

Еще одна хорошая идея - ограничить себя и других разработчиков в создании экземпляров класса SlotGroupN без ссылки на элемент класса ClientInfo, SlotData без ссылки на SlotGroup. Для этого вы должны сделать конструкторы по умолчанию приватными и добавить конструктор с параметром ClientInfo

public SlotGroupBase(ClientInfo ci) 
0 голосов
/ 14 февраля 2012

Расширяя ваш дизайн ...

using System.Drawing;

public class SlotData
{
    private PointF _one;
    private PointF _two;

    internal SizeF Skew {get; set;}

    public PointF One 
    {
        get
        {
            return PointF.Add(_one, Skew);
        }
        set {_one = value; }
    }

    public PointF Two 
    {
        get
        {
            return PointF.Add(_two, Skew);
        }
        set {_two = value; }
    }
}

public class SlotGroup : List<SlotData>
{
    internal SizeF Skew
    {
        set
        {
            foreach(var slotData in this)
            {
                slotData.Skew = value;
            }
        }
    }
}

public class ClientData : List<SlotGroup>
{
    private SizeF _skew;

    public SizeF Skew
    {
        get { return _skew; }

        set
        {
            _skew = value;
            foreach (var slotGroup in this)
            {
                slotGroup.Skew = value;
            }
        }
    }
}

Я не мог придумать ничего более изящного, который бы работал.Инкапсуляция требует, чтобы содержащиеся классы не могли получить доступ к данным своего контейнера, и код для переопределения дочерних элементов доступа к классам контейнера был бы более громоздким.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...