Home
Manage Your Code
Snippet: Strongly typed sub-lists which modify the parent-list (without events) (C#)
Title: Strongly typed sub-lists which modify the parent-list (without events) Language: C#
Description: A class which wraps a parent list containing mixed object types, to provide smaller strongly typed sub-lists of objects. These sub-lists can be modified, which then modifies the parent list concurrently (without events being triggered). Views: 315
Author: Bryan Lyman Date Added: 10/13/2011
Copy Code  
1/// <summary>

2/// A class which wraps a parent list containing mixed object types, to

3/// provide smaller strongly typed sub-lists of objects.

4/// These sub-lists can be modified, which then modifies the parent list

5/// concurrently (without events being triggered).

6/// <para>Class is serializable</para>.

7/// </summary>

8/// <typeparam name="L">Type of objects in the sub list</typeparam>

9/// <typeparam name="P">The type objects in the parent list

10/// (from which <typeparamref name="L"/> derives or implements) </typeparam>

11[Serializable]
12public sealed class SubList<L, P> : IList<L>
13{
14    private List<P> _parentList;
15    private List<L> _tempList; //memory holder (for enumeration)

16 
17    /// <summary>

18    /// For deserializer only. Do not use this constructor.

19    /// </summary>

20    internal protected SubList() { }
21 
22    /// <summary>

23    /// List Constructor

24    /// </summary>

25    /// <param name="parentList">Reference to a parent list which contains mixed objects derived from <typeparamref name="P"/></param>        

26    public SubList(ref List<P> parentList)
27    {
28        //construct the reference if a null value is passed

29        if (parentList == null)
30            parentList = new List<P>();
31        this._parentList = parentList;
32    }
33 
34    /// <summary>

35    /// Create a shallow copy of this sublist to a list of type <typeparamref name="L"/>

36    /// </summary>

37    /// <returns>A strongly typed list copy of the the objects of type <typeparamref name="L"/></returns>

38    public List<L> ShallowCopy()
39    {
40        List<L> ret = new List<L>();
41        this._parentList.ForEach(delegate(P item)
42        {
43            if (item is L)
44                ret.Add((L)(object)item);
45        });
46        return ret;
47    }
48 
49    public L[] ToArray()
50    {
51        List<L> ret = this.ShallowCopy();
52        return ret.ToArray();
53    }
54 
55    public bool IsParentValid()
56    {
57        return (this._parentList != null);
58    }
59 
60    public bool IsValid(L item)
61    {
62        return (this.IsParentValid() && item is P);
63    }
64 
65    public void Merge(List<L> list)
66    {
67        list.ForEach(delegate(L item)
68        {
69            if (IsValid(item) && !this._parentList.Contains((P)(object)item))
70                this._parentList.Add((P)(object)item);
71        });
72    }
73     #region IList<L> Members   ...     #endregion
113     #region ICollection<L> Members   ...     #endregion
167     #region IEnumerable<L> Members   ...     #endregion
176     #region IEnumerable Members   ...     #endregion
184}
185
186//example of how to implement serialization-------------------------------------

187 
188[Serializable, DesignerCategory("code")]
189public abstract class Base
190{   
191    /// <summary>

192    /// for deserializer only

193    /// </summary>

194    internal Base() { }
195}
196 
197[Serializable, DesignerCategory("code")]
198[XmlType("IndexItemAdd")]
199public class Add : Base
200{    
201    /// <summary>

202    /// for deserializer only

203    /// </summary>

204    internal Add() : base() { }
205}
206 
207[Serializable, DesignerCategory("code")]
208[XmlType("IndexItemDelete")]
209public class Delete : Base
210{
211    /// <summary>

212    /// for deserializer only

213    /// </summary>

214    internal Delete() : base() { }
215}
216 
217[Serializable()]
218[DesignerCategory("code")]
219[XmlType("IndexItem")]
220public class IndexItem
221{
222    private List<Base> allItems;
223    private SubList<Add, Base> indexItemAddFields;
224    private SubList<Delete, Base> indexItemDeleteFields;
225 
226    [XmlElement("IndexItemAdd")]
227    public SubList<Add, Base> Adds
228    {
229        get { return this.indexItemAddFields; }
230        set
231        {
232            if (value != null && value.IsParentValid())
233                this.indexItemAddFields = value;
234            else
235                this.indexItemAddFields = new SubList<Add, Base>(ref allItems);
236        }
237    }
238 
239    [XmlElement("IndexItemDelete")]
240    public SubList<Delete, Base> Deletes
241    {
242        get { return this.indexItemDeleteFields; }
243        set
244        {
245            if (value != null && value.IsParentValid())
246                this.indexItemDeleteFields = value;
247            else
248                this.indexItemDeleteFields = new SubList<Delete, Base>(ref allItems);
249        }
250    }
251 
252    [XmlIgnore]
253    public List<Base> Items
254    {
255        get { return this.allItems; }
256    }
257}
Usage
See implementation at the bottom of the code snippet.
Notes
Supports the merging of other lists of the same type. Supports serialization. Supports parent list auto-instantiation.