Category Archives: Collections

Cinchoo – Collections, NestedList, Part 1

ChoNestedList

.NET provides standard List<T> collection class that represents strongly typed list of objects that can be accessed by index. But lacks to store and access another List<T> object as an item. Cinchoo provides this elegant feature through ChoNestedList<T> collection class, where you can store another List<T> or ChoNestedList<T> object as an item along with other strongly typed objects. It provides endless nested opportunity to store items. It exposes most of the List<T> object members.

How to use

1. Add reference to Cinchoo.Core.dll assembly

2. Namespace Cinchoo.Core.Collections.Generic

Sample code,

static void Main(string[] args)
{
    ChoNestedList topList = new ChoNestedList();
    topList.Add("TopList-Tom");
    topList.Add("TopList-Mark");

    ChoNestedList nestedList1 = new ChoNestedList();
    nestedList1.Add("NestedList1-Raj");
    nestedList1.Add("NestedList1-Peter");
    nestedList1.Add("NestedList1-Samuel");
    topList.Add(nestedList1);

    topList.Add("TopList-Nancy");

    foreach (string name in topList)
        Console.WriteLine(name);
}

When you run the above code, the output will be

TopList-Tom
TopList-Mark
NestedList1-Raj
NestedList1-Peter
NestedList1-Samuel
TopList-Nancy
Press any key to continue . . .

It provides most of the IList<T> members

void AddRange(IEnumerable<T> collection);
int BinarySearch(T item);
int BinarySearch(T item, IComparer<T> comparer);
int BinarySearch(int index, int count, T item, IComparer<T> comparer);
List<TOutput> ConvertAll<TOutput>(Converter<T, TOutput> converter);
void CopyTo(int index, T[] array, int arrayIndex, int count);
void CopyTo(T[] array);
bool Exists(Predicate<T> match);
T Find(Predicate<T> match);
List<T> FindAll(Predicate<T> match);
int FindIndex(Predicate<T> match);
int FindIndex(int startIndex, int count, Predicate<T> match);
int FindIndex(int startIndex, Predicate<T> match);
T FindLast(Predicate<T> match);
int FindLastIndex(int startIndex, Predicate<T> match);
int FindLastIndex(int startIndex, int count, Predicate<T> match);
int FindLastIndex(Predicate<T> match);
void ForEach(Action<T> action);
List<T> GetRange(int index, int count);
int IndexOf(T item, int index);
int IndexOf(T item, int index, int count);
void InsertRange(int index, IEnumerable<T> collection);
int LastIndexOf(T item, int index);
int LastIndexOf(T item, int index, int count);
int LastIndexOf(T item);
int RemoveAll(Predicate<T> match);
void RemoveRange(int index, int count);
void Reverse(int index, int count);
void Reverse();
T[] ToArray();
void TrimExcess();
bool TrueForAll(Predicate<T> match);

Also, it is ObservableCollection. It can be used to bind to WPF controls as well.

Advertisement

Cinchoo – Collections, NestedDictionary, Part 1

ChoNestedDictionary

.NET provides standard Dictionary<> collection class that represents strongly typed collection of key, value pairs. But lacks to store and access another Dictionary<> object as an item. Cinchoo provides this feature through ChoNestedDictionary<> collection class, where you can store another Dictionary<> or ChoNestedDictionary<> object as an item along with other strongly typed key-value pairs. It provides endless nested opportunity to store items. It exposes most of the Dictionary<> object members.

How to use

1. Add reference to Cinchoo.Core.dll assembly

2. Namespace Cinchoo.Core.Collections.Generic

Sample code,

static void Main(string[] args)
{
    ChoNestedDictionary outerDict = new ChoNestedDictionary();

    outerDict.Add(1, "outerDict-Tom");
    outerDict.Add(2, "outerDict-Mark");

    ChoNestedDictionary innerDict1 = new ChoNestedDictionary();
    innerDict1.Add(11, "innerDict1-Raj");
    innerDict1.Add(12, "innerDict1-Paul");
    outerDict.Add(innerDict1);

    Dictionary innerDict2 = new Dictionary();
    innerDict2.Add(21, "innerDict2-Mick");
    innerDict2.Add(22, "innerDict2-Donald");
    outerDict.Add(innerDict2);

    outerDict.Add(3, "Daniel");
    outerDict.Add(4, "Pamila");

    foreach (KeyValuePair keyValuePair in outerDict)
        Console.WriteLine(String.Format("Key: {0}, Value: {1}", keyValuePair.Key, keyValuePair.Value));
}

When you run the above code, the output will be

Key: 1, Value: outerDict-Tom
Key: 2, Value: outerDict-Mark
Key: 11, Value: innerDict1-Raj
Key: 12, Value: innerDict1-Paul
Key: 21, Value: innerDict2-Mick
Key: 22, Value: innerDict2-Donald
Key: 3, Value: Daniel
Key: 4, Value: Pamila
Press any key to continue . . .

Cinchoo – ChoCircularEnumerator

ChoCircularEnumerator

Cinchoo provides number of helper classes. ChoCircularEnumerator is one of the helper class to iterate over collection items in circular manner. In order to avoid infinite iteration over the collection items, you must provide number of circular iteration while creating enumerator.

How to use

1. Add reference to Cinchoo.Core.dll assembly

2. Namespace Cinchoo.Core.Collections.Generic or Cinchoo.Core.Collections

Using it on Generic Collections

Use Cinchoo.Core.Collection.Generic namespace.

Sample 1: Here we will see how to use it on List<> object, with 2 iterations

static void Main(string[] args)
{
    List<string> symbols = new List<string>();

    for (int x = 0; x < 5; x++)
        symbols.Add(String.Format("ITEM{0}", x));

    int counter = 0;
    foreach (string symbol in new ChoCircularEnumerator<string>(symbols, 2))
    {
        Console.WriteLine("{0}. {1}", ++counter, symbol);
    }
}

When you run the above code, the output will be

1. ITEM0
2. ITEM1
3. ITEM2
4. ITEM3
5. ITEM4
6. ITEM0
7. ITEM1
8. ITEM2
9. ITEM3
10. ITEM4
Press any key to continue . . .

Sample 2: Here we will see how to use it on Dictionary<> object , with 2 iterations

static void Main(string[] args)
{
    Dictionary<int, string> symbols = new Dictionary<int, string>();

    for (int x = 0; x < 5; x++)
        symbols.Add(x, String.Format("VALUE{0}", x));

    foreach (KeyValuePair keyValue in new ChoCircularEnumerator<KeyValuePair<int, string>>(symbols, 2))
    {
        Console.WriteLine("{0}. {1}", keyValue.Key, keyValue.Value);
    }
}

When you run the above code, the output will be

0. ITEM0
1. ITEM1
2. ITEM2
3. ITEM3
4. ITEM4
0. ITEM0
1. ITEM1
2. ITEM2
3. ITEM3
4. ITEM4
Press any key to continue . . .

Using it on Non Generic Collections

Use Cinchoo.Core.Collection namespace.

Sample 3: Here we will see how to use it on ArrayList object, with 2 iterations

static void Main(string[] args)
{
    ArrayList symbols = new ArrayList();

    for (int x = 0; x < 5; x++)
        symbols.Add(String.Format("ITEM{0}", x));

    int counter = 0;
    foreach (object symbol in new ChoCircularEnumerator(symbols, 2))
    {
        Console.WriteLine("{0}. {1}", ++counter, symbol);
    }
}

When you run the above code, the output will be

1. ITEM0
2. ITEM1
3. ITEM2
4. ITEM3
5. ITEM4
6. ITEM0
7. ITEM1
8. ITEM2
9. ITEM3
10. ITEM4
Press any key to continue . . .

Sample 4: Here we will see how to use it on Hashtable object, with 2 iterations

static void Main(string[] args)
{
    Hashtable hash = new Hashtable();

    for (int x = 0; x < 5; x++)
        hash.Add(x, String.Format("VALUE{0}", x));

    foreach (DictionaryEntry dictEntry in new ChoCircularEnumerator(hash, 2))
    {
        Console.WriteLine("{0}. {1}", dictEntry.Key, dictEntry.Value);
    }
}

When you run the above code, the output will be

4. VALUE4
3. VALUE3
2. VALUE2
1. VALUE1
0. VALUE0
4. VALUE4
3. VALUE3
2. VALUE2
1. VALUE1
0. VALUE0
Press any key to continue . . .

Cinchoo – ChoSteppedEnumerator

ChoSteppedEnumerator

This is one another custom enumerator that Cinchoo framework provides. ChoSteppedEnumerator is a custom enumerator iterates over collection items while skipping some items.

How to use

1. Add reference to Cinchoo.Core.dll assembly

2. Namespace Cinchoo.Core.Collections.Generic or Cinchoo.Core.Collections

Using it on Generic Collections

Use Cinchoo.Core.Collection.Generic namespace.

Sample 1: Here we will see how to use it on List<> object, with 2 steps

static void Main(string[] args)
{
    List<string> symbols = new List<string>();

    for (int x = 0; x < 7; x++)
        symbols.Add(String.Format("ITEM{0}", x));

    int counter = 0;
    foreach (string symbol in new ChoSteppedEnumerator<string>(symbols, 2))
    {
        Console.WriteLine("{0}. {1}", ++counter, symbol);
    }
}

When you run the above code, the output will be

1. ITEM0
2. ITEM3
3. ITEM6
Press any key to continue . . .

Sample 2: Here we will see how to use it on Dictionary<> object , with 2 steps

static void Main(string[] args)
{
    Dictionary<int, string> symbols = new Dictionary<int, string>();

    for (int x = 0; x < 7; x++)
        symbols.Add(x, String.Format("VALUE{0}", x));

    foreach (KeyValuePair<int, string> keyValue in new ChoSteppedEnumerator<KeyValuePair<int, string>>(symbols, 2))
    {
        Console.WriteLine("{0}. {1}", keyValue.Key, keyValue.Value);
    }
}

When you run the above code, the output will be

0. ITEM0
3. ITEM3
6. ITEM6
Press any key to continue . . .

Using it on Non Generic Collections

Use Cinchoo.Core.Collection namespace.

Sample 3: Here we will see how to use it on ArrayList object, with 2 steps

static void Main(string[] args)
{
    ArrayList symbols = new ArrayList();

    for (int x = 0; x < 7; x++)
        symbols.Add(String.Format("ITEM{0}", x));

    int counter = 0;
    foreach (object symbol in new ChoSteppedEnumerator(symbols, 2))
    {
        Console.WriteLine("{0}. {1}", ++counter, symbol);
    }
}

When you run the above code, the output will be

1. ITEM0
2. ITEM3
3. ITEM6
Press any key to continue . . .

Sample 4: Here we will see how to use it on Hashtable object, with 2 steps

static void Main(string[] args)
{
    Hashtable hash = new Hashtable();

    for (int x = 0; x < 7; x++)
        hash.Add(x, String.Format("VALUE{0}", x));

    foreach (DictionaryEntry dictEntry in new ChoSteppedEnumerator(hash, 2))
    {
        Console.WriteLine("{0}. {1}", dictEntry.Key, dictEntry.Value);
    }
}

When you run the above code, the output will be

6. VALUE6
3. VALUE3
0. VALUE0
Press any key to continue . . .

Cinchoo – ChoReverseEnumerator

ChoReverseEnumerator

This is one another custom enumerator that Cinchoo framework provides. ChoReverseEnumerator is a custom enumerator iterates over collection items in reverse order.

How to use

1. Add reference to Cinchoo.Core.dll assembly

2. Namespace Cinchoo.Core.Collections.Generic or Cinchoo.Core.Collections

Using it on Generic Collections

Use Cinchoo.Core.Collection.Generic namespace.

Sample 1: Here we will see how to use it on List<> object

static void Main(string[] args)
{
    List<string> symbols = new List<string>();

    for (int x = 0; x < 5; x++)
        symbols.Add(String.Format("ITEM{0}", x));

    int counter = 0;
    foreach (string symbol in new ChoReverseEnumerator<string>(symbols))
    {
        Console.WriteLine("{0}. {1}", ++counter, symbol);
    }
}

When you run the above code, the output will be

1. ITEM4
2. ITEM3
3. ITEM2
4. ITEM1
5. ITEM0
Press any key to continue . . .

Sample 2: Here we will see how to use it on Dictionary<> object

static void Main(string[] args)
{
    Dictionary<int, string> symbols = new Dictionary<int, string>();

    for (int x = 0; x < 5; x++)
        symbols.Add(x, String.Format("VALUE{0}", x));

    foreach (KeyValuePair<int, string> keyValue in new ChoReverseEnumerator<KeyValuePair<int, string>>(symbols))
    {
        Console.WriteLine("{0}. {1}", keyValue.Key, keyValue.Value);
    }
}

When you run the above code, the output will be

4. VALUE4
3. VALUE3
2. VALUE2
1. VALUE1
0. VALUE0
Press any key to continue . . .

Using it on Non Generic Collections

Use Cinchoo.Core.Collection namespace.

Sample 3: Here we will see how to use it on ArrayList object, with 2 steps

static void Main(string[] args)
{
    ArrayList symbols = new ArrayList();

    for (int x = 0; x < 5; x++)
        symbols.Add(String.Format("ZITEM{0}", x));

    int counter = 0;
    foreach (object symbol in new ChoReverseEnumerator(symbols))
    {
        Console.WriteLine("{0}. {1}", ++counter, symbol);
    }
}

When you run the above code, the output will be

1. ZITEM4
2. ZITEM3
3. ZITEM2
4. ZITEM1
5. ZITEM0
Press any key to continue . . .

Sample 4: Here we will see how to use it on Hashtable object, with 2 steps

static void Main(string[] args)
{
    Hashtable hash = new Hashtable();

    for (int x = 0; x < 5; x++)
        hash.Add(x, String.Format("VALUE{0}", x));

    foreach (DictionaryEntry dictEntry in new ChoReverseEnumerator(hash))
    {
        Console.WriteLine("{0}. {1}", dictEntry.Key, dictEntry.Value);
    }
}

When you run the above code, the output will be

0. VALUE0
1. VALUE1
2. VALUE2
3. VALUE3
4. VALUE4
Press any key to continue . . .

Cinchoo – ChoConstraintEnumerator

ChoConstraintEnumerator

This is one another custom enumerator that Cinchoo framework provides. ChoConstraintEnumerator is a custom enumerator iterates over collection items matches the passed constraint logic.

How to use

1. Add reference to Cinchoo.Core.dll assembly

2. Namespace Cinchoo.Core.Collections.Generic or Cinchoo.Core.Collections

Using it on Generic Collections

Use Cinchoo.Core.Collection.Generic namespace.

Sample 1: Here we will see how to use it on List<> object, matches items having value 3 or 5

static void Main(string[] args)
{
    List<string> symbols = new List<string>();

    for (int x = 0; x < 7; x++)
        symbols.Add(String.Format("ITEM{0}", x));

    int counter = 0;
    foreach (string symbol in new ChoConstraintEnumerator<string>(symbols, (x) => x.EndsWith("3") || x.EndsWith("5")))
    {
        Console.WriteLine("{0}. {1}", ++counter, symbol);
    }
}

When you run the above code, the output will be

1. ITEM3
2. ITEM5
Press any key to continue . . .

Sample 2: Here we will see how to use it on Dictionary<> object, matches items having key either 3 or 5

static void Main(string[] args)
{
    Dictionary<int, string> dict = new Dictionary<int, string>();

    for (int x = 0; x < 7; x++)
        dict.Add(x, String.Format("VALUE{0}", x));

    foreach (KeyValuePair<int, string> keyValue in new ChoConstraintEnumerator<KeyValuePair<int, string>>(dict, (x) => x.Key == 3 || x.Key == 5))
    {
        Console.WriteLine("{0}. {1}", keyValue.Key, keyValue.Value);
    }
}

When you run the above code, the output will be

3. VALUE3
5. VALUE5
Press any key to continue . . .

Using it on Non Generic Collections

Use Cinchoo.Core.Collection namespace.

Sample 3: Here we will see how to use it on ArrayList object, matches items having value 3 or 5

static void Main(string[] args)
{
    ArrayList symbols1 = new ArrayList();

    for (int x = 0; x < 7; x++)
        symbols1.Add(String.Format("ZITEM{0}", x));

    int counter1 = 0;
    foreach (object symbol in new ChoConstraintEnumerator(symbols1, (x) => x.ToString().EndsWith("3") || x.ToString().EndsWith("5")))
    {
        Console.WriteLine("{0}. {1}", ++counter1, symbol);
    }
}

When you run the above code, the output will be

1. ZITEM3
2. ZITEM5
Press any key to continue . . .

Sample 4: Here we will see how to use it on Hashtable object, matches items having key either 3 or 5

static void Main(string[] args)
{
    Hashtable hash = new Hashtable();

    for (int x = 0; x < 7; x++)
        hash.Add(x, String.Format("VALUE{0}", x));

    foreach (DictionaryEntry dictEntry in new ChoConstraintEnumerator(hash, (x) => ((DictionaryEntry)x).Key.ToString() == "3" || ((DictionaryEntry)x).Key.ToString() == "5"))
    {
        Console.WriteLine("{0}. {1}", dictEntry.Key, dictEntry.Value);
    }
}

When you run the above code, the output will be

5. VALUE5
3. VALUE3
Press any key to continue . . .

Cinchoo – ChoSynchronizedEnumerator

ChoSynchronizedEnumerator

This is one another custom enumerator that Cinchoo framework provides. ChoSynchronizedEnumerator is a custom enumerator iterates over collection items synchronized way in multi-threaded applications.

How to use

1. Add reference to Cinchoo.Core.dll assembly

2. Namespace Cinchoo.Core.Collections.Generic or Cinchoo.Core.Collections

Using it on Generic Collections

Use Cinchoo.Core.Collection.Generic namespace.

Sample 1: Here we will see how to use it on List<> object,

Below sample iterates over List<> object by two threads simultaneously.

static void Main(string[] args)
{
    object syncRoot = new object();
    List<string> symbols = new List<string>();

    for (int x = 0; x < 5; x++)
        symbols.Add(String.Format("ITEM{0}", x));

    ManualResetEvent evt = new ManualResetEvent(false);
    for (int z = 0; z < 2; z++)
    {
        ThreadPool.QueueUserWorkItem((state) =>
            {
                Thread.CurrentThread.Name = String.Format("Thread_{0}", state);
                evt.WaitOne();
                int counter = 0;
                foreach (string symbol in new ChoSynchronizedEnumerator<string>(symbols, syncRoot))
                {
                    Console.WriteLine("{0}. {1} -- {2}", ++counter, symbol, Thread.CurrentThread.Name);
                }
            }, z);
    }

    evt.Set();
    Console.WriteLine("Press any key to continue...");
    Console.ReadLine();
}

When you run the above code, you will see the output consistently all the time as below. In a non-synchronous model, the output will product unpredictable sequence of results.

1. ITEM0 -- Thread_0
2. ITEM1 -- Thread_0
3. ITEM2 -- Thread_0
4. ITEM3 -- Thread_0
5. ITEM4 -- Thread_0
1. ITEM0 -- Thread_1
2. ITEM1 -- Thread_1
3. ITEM2 -- Thread_1
4. ITEM3 -- Thread_1
5. ITEM4 -- Thread_1
Press any key to continue . . .

Sample 2: Here we will see how to use it on Dictionary<> object

Below sample iterates over Dictionary<> object by two threads simultaneously.

static void Main(string[] args)
{
    object syncRoot = new object();
    Dictionary<int, string> dict = new Dictionary<int, string>();

    for (int x = 0; x < 5; x++)
        dict.Add(x, String.Format("VALUE{0}", x));

    ManualResetEvent evt = new ManualResetEvent(false);
    for (int z = 0; z < 2; z++)
    {
        ThreadPool.QueueUserWorkItem((state) =>
            {
                Thread.CurrentThread.Name = String.Format("Thread_{0}", state);
                evt.WaitOne();
                int counter = 0;
                foreach (KeyValuePair<int, string> keyValue in new ChoSynchronizedEnumerator<KeyValuePair<int, string>>(dict, syncRoot))
                {
                    Console.WriteLine("{0}. {1} -- {2}", keyValue.Key, keyValue.Value, Thread.CurrentThread.Name);
                }
            }, z);
    }

    evt.Set();
    Console.WriteLine("Press any key to continue...");
    Console.ReadLine();
}

When you run the above code, you will see the output consistently all the time as below. In a non-synchronous model, the output will product unpredictable sequence of results.

0. VALUE0 -- Thread_0
1. VALUE1 -- Thread_0
2. VALUE2 -- Thread_0
3. VALUE3 -- Thread_0
4. VALUE4 -- Thread_0
0. VALUE0 -- Thread_1
1. VALUE1 -- Thread_1
2. VALUE2 -- Thread_1
3. VALUE3 -- Thread_1
4. VALUE4 -- Thread_1
Press any key to continue . . .

Using it on Non Generic Collections

Use Cinchoo.Core.Collection namespace.

Sample 3: Here we will see how to use it on ArrayList object

Below sample iterates over ArrayList object by two threads simultaneously.

static void Main(string[] args)
{
    object syncRoot = new object();
    ArrayList symbols = new ArrayList();

    for (int x = 0; x < 5; x++)
        symbols.Add(String.Format("ZITEM{0}", x));

    ManualResetEvent evt = new ManualResetEvent(false);
    for (int z = 0; z < 2; z++)
    {
        ThreadPool.QueueUserWorkItem((state) =>
            {
                Thread.CurrentThread.Name = String.Format("Thread_{0}", state);
                evt.WaitOne();
                int counter = 0;
                foreach (string symbol in new ChoSynchronizedEnumerator(symbols, syncRoot))
                {
                    Console.WriteLine("{0}. {1} -- {2}", ++counter, symbol, Thread.CurrentThread.Name);
                }
            }, z);
    }

    evt.Set();
    Console.WriteLine("Press any key to continue...");
    Console.ReadLine();
}

When you run the above code, you will see the output consistently all the time as below. In a non-synchronous model, the output will product unpredictable sequence of results.

1. ZITEM0 -- Thread_0
2. ZITEM1 -- Thread_0
3. ZITEM2 -- Thread_0
4. ZITEM3 -- Thread_0
5. ZITEM4 -- Thread_0
1. ZITEM0 -- Thread_1
2. ZITEM1 -- Thread_1
3. ZITEM2 -- Thread_1
4. ZITEM3 -- Thread_1
5. ZITEM4 -- Thread_1
Press any key to continue . . .

Sample 4: Here we will see how to use it on Hashtable object,

Below sample iterates over Hashtable object by two threads simultaneously.

static void Main(string[] args)
{
    object syncRoot = new object();
    Hashtable dict = new Hashtable();

    for (int x = 0; x < 5; x++)
        dict.Add(x, String.Format("VALUE{0}", x));

    ManualResetEvent evt = new ManualResetEvent(false);
    for (int z = 0; z < 2; z++)
    {
        ThreadPool.QueueUserWorkItem((state) =>
            {
                Thread.CurrentThread.Name = String.Format("Thread_{0}", state);
                evt.WaitOne();
                foreach (DictionaryEntry dictEntry in new ChoSynchronizedEnumerator(dict, syncRoot))
                {
                    Console.WriteLine("{0}. {1} -- {2}", dictEntry.Key, dictEntry.Value, Thread.CurrentThread.Name);
                }
            }, z);
    }

    evt.Set();
    Console.WriteLine("Press any key to continue...");
    Console.ReadLine();
}

When you run the above code, you will see the output consistently all the time as below. In a non-synchronous model, the output will product unpredictable sequence of results.

4. VALUE4 -- Thread_0
3. VALUE3 -- Thread_0
2. VALUE2 -- Thread_0
1. VALUE1 -- Thread_0
0. VALUE0 -- Thread_0
4. VALUE4 -- Thread_1
3. VALUE3 -- Thread_1
2. VALUE2 -- Thread_1
1. VALUE1 -- Thread_1
0. VALUE0 -- Thread_1
Press any key to continue . . .

PS: Please be careful about using this enumerator, you must dispose the enumerator to order to avoid contention, deadlock issues.

Cinchoo – Collections, NestedList, Part 2

XmlSerialization

Now you can serialize/deserialize the ChoNestedList<T> to/from xml. Here is how

Serialize

Here you can see how to serialize ChoNestedList<T> object to xml string.

1. Add reference to Cinchoo.Core.dll assembly

2. Namespace Cinchoo.Core.Collections.Generic

Sample code,

static void Main(string[] args)
{
    ChoNestedList<string> topList = new ChoNestedList<string>();
    topList.Add("TopList-Tom");
    topList.Add("TopList-Mark");

    ChoNestedList<string> nestedList1 = new ChoNestedList<string>();
    nestedList1.Add("NestedList1-Raj");
    nestedList1.Add("NestedList1-Peter");
    nestedList1.Add("NestedList1-Samuel");
    topList.Add(nestedList1);

    topList.Add("TopList-Nancy");

    Console.WriteLine(topList.ToXml());
}

When you run the above code, the output will be

<ChoNestedList>
  <ChoTuple>
    <First><string>TopList-Tom</string></First>
    <Second />
  </ChoTuple>
  <ChoTuple>
    <First><string>TopList-Mark</string></First>
    <Second />
  </ChoTuple>
  <ChoTuple>
    <First />
    <Second><ChoNestedList>
  <ChoTuple>
    <First><string>NestedList1-Raj</string></First>
    <Second />
  </ChoTuple>
  <ChoTuple>
    <First><string>NestedList1-Peter</string></First>
    <Second />
  </ChoTuple>
  <ChoTuple>
    <First><string>NestedList1-Samuel</string></First>
    <Second />
  </ChoTuple>
</ChoNestedList></Second>
  </ChoTuple>
  <ChoTuple>
    <First><string>TopList-Nancy</string></First>
    <Second />
  </ChoTuple>
</ChoNestedList>
Press any key to continue . . .

Deserialize

In here, you can see how to deserialize a xml string to ChoNestedList<T> object.

1. Add reference to Cinchoo.Core.dll assembly

2. Namespace Cinchoo.Core.Collections.Generic

Sample code,

static void Main(string[] args)
{
    ChoNestedList<string> topList = new ChoNestedList<string>();
    topList.Add("TopList-Tom");
    topList.Add("TopList-Mark");

    ChoNestedList<string> nestedList1 = new ChoNestedList<string>();
    nestedList1.Add("NestedList1-Raj");
    nestedList1.Add("NestedList1-Peter");
    nestedList1.Add("NestedList1-Samuel");
    topList.Add(nestedList1);

    topList.Add("TopList-Nancy");

    string xml = topList.ToXml();
    ChoNestedList<string> deserializedList = xml.ToObjectFromXml<ChoNestedList<string>>();

    for (int index = 0; index < deserializedList.Count; index++)
        Console.WriteLine(deserializedList[index]);
}

When you run the above code, the output will be

TopList-Tom
TopList-Mark
NestedList1-Raj
NestedList1-Peter
NestedList1-Samuel
TopList-Nancy
Press any key to continue . . .

Cinchoo – Collections, NestedList, Part 3

BinarySerialization

Now you can serialize/deserialize a ChoNestedList<T> object in binary format. Here is how

1. Add reference to Cinchoo.Core.dll assembly

2. Namespace Cinchoo.Core.Collections.Generic

Sample code,

static void Main(string[] args)
{
    ChoNestedList topList = new ChoNestedList();
    topList.Add("TopList-Tom");
    topList.Add("TopList-Mark");

    ChoNestedList nestedList1 = new ChoNestedList();
    nestedList1.Add("NestedList1-Raj");
    nestedList1.Add("NestedList1-Peter");
    nestedList1.Add("NestedList1-Samuel");
    topList.Add(nestedList1);

    topList.Add("TopList-Nancy");

    ChoNestedList clonedTopList = null;
    using (MemoryStream buffer = new MemoryStream())
    {
        BinaryFormatter formatter = new BinaryFormatter();

        formatter.Serialize(buffer, topList);
        buffer.Seek(0, SeekOrigin.Begin);
        clonedTopList = (ChoNestedList)formatter.Deserialize(buffer);
    }

    for (int index = 0; index < clonedTopList.Count; index++)
        Console.WriteLine(clonedTopList[index]);
}

When you run the above code, the output will be

TopList-Tom
TopList-Mark
NestedList1-Raj
NestedList1-Peter
NestedList1-Samuel
TopList-Nancy
Press any key to continue . . .

Cinchoo – Collections, NestedList, Part 4

Clone

ChoNestedList<T> provides deep cloning through ICloneable interface.

1. Add reference to Cinchoo.Core.dll assembly

2. Namespace Cinchoo.Core.Collections.Generic

Sample code,

static void Main(string[] args)
{
    ChoNestedList<string> topList = new ChoNestedList<string>();
    topList.Add("TopList-Tom");
    topList.Add("TopList-Mark");

    ChoNestedList<string> nestedList1 = new ChoNestedList<string>();
    nestedList1.Add("NestedList1-Raj");
    nestedList1.Add("NestedList1-Peter");
    nestedList1.Add("NestedList1-Samuel");
    topList.Add(nestedList1);

    topList.Add("TopList-Nancy");

    ChoNestedList<string> clonedTopList = topList.Clone<ChoNestedList<string>>();

    for (int index = 0; index < clonedTopList.Count; index++)
        Console.WriteLine(clonedTopList[index]);
}

When you run the above code, the output will be

TopList-Tom
TopList-Mark
NestedList1-Raj
NestedList1-Peter
NestedList1-Samuel
TopList-Nancy
Press any key to continue . . .