Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

|Поправлено| Что можно придумать, чтобы код заработал так, как требуется?

84K
11 октября 2012 года
Mahi
11 / / 11.10.2012
Объект класса First принимает объекты класса Second складывает их в чистом виде в коллекцию (private IList<Second> _scndList), а так же создает еще одну коллекцию (private IList<int> _iList), куда складывает подряд все элементы Second._iList.
Таким образом First формирует у себя две коллекции.

Беда в том, что после добавления объекта класса Second объектом класса First ( FirstObj.Add(SecondObj); ) остается возможность изменять уже добавленный в First объект класса Second. Таким образом класс First не может корректно сформировать вторую коллекцию ( _iList).

Вопрос состоит в том, как сделать так, чтобы предотвращать возможность изменять объекты класса Second после добавления их в коллекцию класса First?

Можно ли создать эти классы таким образом, чтобы попытка изменить объект класса Second после добавления его в First выдавала ошибку компиляции?


Цитата:

Данный код приводит к тому, что объект FirstObj имеет 2 элемента в коллекции scndList и один элемент в коллекции scndListToo. Это некорректный результат. По задумке количество элементов в коллекции должно быть одинаковое количество. Рассинхронизация происходит из-за того, что после выполнения инструкции
FirstObj.Add(SecondObj);
остается возможность внести изменения в объект SecondObj
SecondObj.Add(2);

Подскажите, как правильно создать подобную систему классов? Есть мысль оставить все как есть, только добавлять в коллекцию scndList класса First клонированный объект класса Second, но мне кажется что есть более правильный способ решение подобной задачи.



Код:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication2
{
    public class Second
    {
        private IList<int> _iList = new List<int>();

        public void Add(int iElement)
        {
            this._iList.Add(iElement);
        }

        public int Count
        {
            get
            {
                return this._iList.Count;
            }
        }

        public int this[int index]
        {
            get
            {
                return _iList[index];
            }
        }
    }

    public class First
    {
        private IList<Second> _scndList = new List<Second>();
        private IList<int> _iList = new List<int>();

        public void Add(Second scndElement)
        {
            this._scndList.Add(scndElement);

            for (int i = 0; i < scndElement.Count; i++)
            {
                this._iList.Add(scndElement[i]);
            }
        }

        // возвращает коллекцию _scndList как string
        public string Get1()
        {            
            string strTmp = " |";        
            foreach (Second scndElement in this._scndList)
            {                
                for (int i = 0; i < scndElement.Count; i++)
                {                    
                    strTmp += string.Format(" {0} |",  scndElement[i]);                    
                }
            }
            return strTmp;
        }

        // возвращает коллекцию _iList как string
        public string Get2()
        {
            string strTmp = " |";
            foreach (int i in this._iList)
            {
                strTmp += string.Format(" {0} |", i);
            }
            return strTmp;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Second SecondObj = new Second();
            SecondObj.Add(1);
            SecondObj.Add(2);            

            First FirstObj = new First();
            FirstObj.Add(SecondObj);

            SecondObj = new Second();
            SecondObj.Add(11);
            SecondObj.Add(12);            

            FirstObj.Add(SecondObj); //Second добавляется в First

            SecondObj.Add(-1); //Second изменяется после добавления в First. В результате First._scndList изменяется, а First._iList остается неизменным

            string arr1 = FirstObj.Get1();
            string arr2 = FirstObj.Get2();

        }
    }
}
341
13 октября 2012 года
Der Meister
874 / / 21.12.2007
Выдать ошибку на этапе компиляции у вас не получится.
Можно заменить тип Second._iList c List<int> на массив int[], инициализировать его в конструкторе Second и убрать Second.Add().
Можно воспользоваться ObservableCollection<> и подписываться на событие CollectionChanged.
Можно ввести в Second свойство First Parent {get; private set}, и если его зачение отлично от null, выбрасывать исключение при добавлении элемента (хотя в вашем случае достаточно флага типа bool).
Можно избавиться от First._iList, заменив его методом вроде
Код:
class First {
    // ...
   
    public IEnumerable<int> GetElements() {
        foreach (var second in _scndList) {
            foreach (var element in second) {
                yield return element;
            }
        }
    }
}

class Second : IEnumerable<int> {
    private IList<int> _iList = new List<int>();
   
    public IEnumerator<int> GetEnumerator() { return _iList.GetEnumerator(); }
    IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
   
    // ...
}
Кривизна этих решений примерно одинаково велика - лучше вообще пересмотреть дизайн. Например, непонятно, зачем вообще нужен тип Second.
341
12 октября 2012 года
Der Meister
874 / / 21.12.2007
Выражайтесь яснее, пожалуйста:

84K
15 октября 2012 года
Mahi
11 / / 11.10.2012
Понравился вариант с First Parent { }. Но все равно остается возможность несанкционированного изменения Second.

Покрутил эту задачку и так и сяк. В итоге остановился на следующем варианте, он мне показался наиболее простым и правильным:

Код:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication2
{
    public class First
    {
        class Second
        {
            private IList<int> _iList = new List<int>();
            private string _catalogName;

            public Second(string strName)
            {
                this._catalogName = strName;
            }
           
            public void Add(int iElement)
            {
                this._iList.Add(iElement);
            }
                   
            public int Count
            {
                get
                {
                    return this._iList.Count;
                }
            }
           
            public int this[int index]
            {
                get
                {
                    if (index < this.Count)
                    {
                        return this._iList[index];
                    }
                    return -1;
                }
            }
        }

        private Second _scndCurrent;
        private IList<Second> _scndList = new List<Second>();

        // Сформировать эту коллекцию - основная задача.
        private IList<int> _iList = new List<int>();      
       
        // Создание нового экземпляра Second
        public void Create(string strElement)
        {
            this._scndCurrent = new Second(strElement);
            this._scndList.Add(this._scndCurrent);
        }
       
        // Добавление элементов в экземпляр Second, который был создан последним
        public void Add(int iElement)
        {
            this._scndCurrent.Add(iElement);
            this._iList.Add(iElement * 10); // Типа анализ и обработка данных
        }

        // Возвращает коллекцию _scndList как string
        public string Get1()
        {
            string strTmp = " |";
            foreach (Second scndElement in this._scndList)
            {
                for (int i = 0; i < scndElement.Count; i++)
                {
                    strTmp += string.Format(" {0} |", scndElement[i]);
                }
            }
            return strTmp;
        }

        // возвращает коллекцию _iList как string
        public string Get2()
        {
            string strTmp = " |";
            foreach (int i in this._iList)
            {
                strTmp += string.Format(" {0} |", i);
            }
            return strTmp;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {

            First FirstObj = new First();
            FirstObj.Create("Первая группа");
            FirstObj.Add(1);
            FirstObj.Add(2);

            FirstObj.Create("Вторая группа");
            FirstObj.Add(11);
            FirstObj.Add(12);

            string arr1 = FirstObj.Get1();
            string arr2 = FirstObj.Get2();

        }
    }
}
Спасибо за помощь.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог