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(); }
// ...
}
|Поправлено| Что можно придумать, чтобы код заработал так, как требуется?
Таким образом 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();
}
}
}
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();
}
}
}
Можно заменить тип Second._iList c List<int> на массив int[], инициализировать его в конструкторе Second и убрать Second.Add().
Можно воспользоваться ObservableCollection<> и подписываться на событие CollectionChanged.
Можно ввести в Second свойство First Parent {get; private set}, и если его зачение отлично от null, выбрасывать исключение при добавлении элемента (хотя в вашем случае достаточно флага типа bool).
Можно избавиться от First._iList, заменив его методом вроде
Код:
Выражайтесь яснее, пожалуйста:
Покрутил эту задачку и так и сяк. В итоге остановился на следующем варианте, он мне показался наиболее простым и правильным:
Код:
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();
}
}
}
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();
}
}
}