Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
ConstrainedList.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 using System;
4 using System.Collections;
5 using System.Collections.Generic;
6 
7 namespace SiliconStudio.Core.Collections
8 {
9  /// <summary>
10  /// Represent a collection associated with a constraint. When an item is added to this collection, it is tested against the constraint.
11  /// If the test fails, the item can either be discarded, or an exception can be thrown. The desired behavior can be defined with <see cref="ThrowException"/>.
12  /// </summary>
13  public class ConstrainedList<T> : IList<T>
14  {
15  private readonly List<T> innerList = new List<T>();
16 
17  private readonly string errorMessage;
18 
19  public ConstrainedList(Func<ConstrainedList<T>, T, bool> constraint = null, bool throwException = true, string errorMessage = null)
20  {
21  Constraint = constraint;
22  ThrowException = throwException;
23  this.errorMessage = errorMessage;
24  }
25 
26  public ConstrainedList()
27  {
28  ThrowException = true;
29  }
30 
31  /// <summary>
32  /// Gets or sets whether the collection should throw an <see cref="ArgumentException"/> when an item to add or insert doesn't pass the constraint.
33  /// </summary>
34  public bool ThrowException { get; set; }
35 
36  /// <summary>
37  /// Gets or sets the constraint for items added to the collection. If <c>null</c>, this collection behaves like a <see cref="List{T}"/>.
38  /// </summary>
39  public Func<ConstrainedList<T>, T, bool> Constraint { get; set; }
40 
41  /// <inheritdoc/>
42  public IEnumerator<T> GetEnumerator()
43  {
44  return innerList.GetEnumerator();
45  }
46 
47  /// <inheritdoc/>
48  IEnumerator IEnumerable.GetEnumerator()
49  {
50  return GetEnumerator();
51  }
52 
53  /// <inheritdoc/>
54  public void Add(T item)
55  {
56  if (CheckConstraint(item))
57  innerList.Add(item);
58  }
59 
60  /// <inheritdoc/>
61  public void Clear()
62  {
63  innerList.Clear();
64  }
65 
66  /// <inheritdoc/>
67  public bool Contains(T item)
68  {
69  return innerList.Contains(item);
70  }
71 
72  /// <inheritdoc/>
73  public void CopyTo(T[] array, int arrayIndex)
74  {
75  innerList.CopyTo(array, arrayIndex);
76  }
77 
78  /// <inheritdoc/>
79  public bool Remove(T item)
80  {
81  return innerList.Remove(item);
82  }
83 
84  /// <inheritdoc/>
85  public int Count { get { return innerList.Count; } }
86 
87  /// <inheritdoc/>
88  public bool IsReadOnly { get { return false; } }
89 
90  /// <inheritdoc/>
91  public int IndexOf(T item)
92  {
93  return innerList.IndexOf(item);
94  }
95 
96  /// <inheritdoc/>
97  public void Insert(int index, T item)
98  {
99  if (CheckConstraint(item))
100  innerList.Insert(index, item);
101  }
102 
103  /// <inheritdoc/>
104  public void RemoveAt(int index)
105  {
106  innerList.RemoveAt(index);
107  }
108 
109  /// <inheritdoc/>
110  public T this[int index] { get { return innerList[index]; } set { if (CheckConstraint(value)) innerList[index] = value; } }
111 
112  private bool CheckConstraint(T item)
113  {
114  bool result = true;
115  if (Constraint != null)
116  {
117  result = Constraint(this, item);
118  if (!result && ThrowException)
119  throw new ArgumentException(errorMessage ?? "The given item does not validate the collection constraint.");
120  }
121 
122  return result;
123  }
124  }
125 }
ConstrainedList(Func< ConstrainedList< T >, T, bool > constraint=null, bool throwException=true, string errorMessage=null)
Represent a collection associated with a constraint. When an item is added to this collection...