44// Created by: Alexey Kochetov
55// Created: 2007.10.01
66
7- using System ;
87using System . Collections ;
9- using System . Collections . Generic ;
108using System . Collections . ObjectModel ;
119using System . Collections . Specialized ;
1210using System . Diagnostics ;
1513using Xtensive . Conversion ;
1614using Xtensive . Core ;
1715
18-
19-
2016namespace Xtensive . Collections
2117{
2218 /// <summary>
@@ -32,42 +28,29 @@ namespace Xtensive.Collections
3228 [ DebuggerDisplay ( "Count = {Count}" ) ]
3329 public class FlagCollection < TKey , TFlag > : LockableBase ,
3430 IList < KeyValuePair < TKey , TFlag > > ,
35- IDictionary < TKey , TFlag > ,
31+ IReadOnlyDictionary < TKey , TFlag > ,
3632 IEquatable < FlagCollection < TKey , TFlag > > ,
3733 ISerializable
3834 {
3935 private const int MaxItemCount = 32 ;
40- private readonly Biconverter < TFlag , bool > converter ;
41- private readonly List < TKey > keys ;
42- private readonly ReadOnlyCollection < TKey > readOnlyKeys ;
36+ private readonly List < TKey > keys = new ( ) ;
4337 private BitVector32 flags ;
4438
4539 /// <summary>
4640 /// Gets <see cref="Biconverter{TFrom,TTo}"/> instance
4741 /// used to convert flag value to <see cref="bool"/> and vice versa.
4842 /// </summary>
49- public Biconverter < TFlag , bool > Converter
50- {
51- [ DebuggerStepThrough ]
52- get { return converter ; }
53- }
43+ public Biconverter < TFlag , bool > Converter { [ DebuggerStepThrough ] get ; }
5444
5545 /// <summary>
5646 /// Gets an <see cref="Collection{T}"/> containing the flags.
5747 /// </summary>
58- public ICollection < TFlag > Flags
59- {
60- [ DebuggerStepThrough ]
61- get { return Values ; }
62- }
48+ public ICollection < TFlag > Flags => Values ;
6349
64- #region IDictionary <TKey,TFlag> Members
50+ #region IReadOnlyDictionary <TKey,TFlag> Members
6551
6652 /// <inheritdoc/>
67- public bool ContainsKey ( TKey key )
68- {
69- return keys . Contains ( key ) ;
70- }
53+ public bool ContainsKey ( TKey key ) => keys . Contains ( key ) ;
7154
7255 /// <inheritdoc/>
7356 public void Add ( TKey key , TFlag flag )
@@ -78,13 +61,20 @@ public void Add(TKey key, TFlag flag)
7861 if ( keys . Count >= MaxItemCount )
7962 throw new InvalidOperationException ( string . Format ( Strings . ExMaxItemCountIsN , MaxItemCount ) ) ;
8063 keys . Add ( key ) ;
81- flags [ 1 << ( keys . Count - 1 ) ] = converter . ConvertForward ( flag ) ;
64+ flags [ 1 << ( keys . Count - 1 ) ] = Converter . ConvertForward ( flag ) ;
8265 }
8366
8467 /// <inheritdoc/>
85- public virtual void Add ( TKey key )
68+ public virtual void Add ( TKey key ) => Add ( key , default ) ;
69+
70+ public bool TryAdd ( TKey key , TFlag flag )
8671 {
87- Add ( key , default ( TFlag ) ) ;
72+ if ( ! ContainsKey ( key ) ) {
73+ Add ( key , flag ) ;
74+ return true ;
75+ }
76+
77+ return false ;
8878 }
8979
9080 /// <inheritdoc/>
@@ -107,11 +97,11 @@ public bool Remove(TKey key)
10797 /// <inheritdoc/>
10898 public bool TryGetValue ( TKey key , out TFlag value )
10999 {
110- value = converter . ConvertBackward ( false ) ;
100+ value = Converter . ConvertBackward ( false ) ;
111101 int index = keys . IndexOf ( key ) ;
112102 if ( index < 0 )
113103 return false ;
114- value = converter . ConvertBackward ( flags [ 1 << index ] ) ;
104+ value = Converter . ConvertBackward ( flags [ 1 << index ] ) ;
115105 return true ;
116106 }
117107
@@ -121,11 +111,7 @@ public TFlag this[TKey key]
121111 get
122112 {
123113 ArgumentValidator . EnsureArgumentIsNotDefault ( key , "key" ) ;
124- TFlag value ;
125- bool result = TryGetValue ( key , out value ) ;
126- if ( ! result )
127- throw new KeyNotFoundException ( ) ;
128- return value ;
114+ return TryGetValue ( key , out var value ) ? value : throw new KeyNotFoundException ( ) ;
129115 }
130116 set
131117 {
@@ -135,58 +121,42 @@ public TFlag this[TKey key]
135121 if ( index < 0 )
136122 Add ( key , value ) ;
137123 else
138- flags [ 1 << index ] = converter . ConvertForward ( value ) ;
124+ flags [ 1 << index ] = Converter . ConvertForward ( value ) ;
139125 }
140126 }
141127
142128 /// <summary>
143129 /// Gets a list of keys.
144130 /// </summary>
145131 /// <returns>A list of keys.</returns>
146- public IReadOnlyList < TKey > Keys
147- {
148- get { return readOnlyKeys ; }
149- }
132+ public IReadOnlyList < TKey > Keys => keys ;
150133
151134 /// <inheritdoc/>
152- ICollection < TKey > IDictionary < TKey , TFlag > . Keys
153- {
154- get { return readOnlyKeys ; }
155- }
135+ IEnumerable < TKey > IReadOnlyDictionary < TKey , TFlag > . Keys => Keys ;
156136
157137 /// <summary>
158138 /// Gets an array of values.
159139 /// </summary>
160140 /// <returns>An array of values.</returns>
161141 public TFlag [ ] Values {
162142 get {
163- var array = new TFlag [ keys . Count ] ;
164- for ( int i = 0 ; i < keys . Count ; i ++ )
165- array [ i ] = converter . ConvertBackward ( flags [ 1 << i ] ) ;
143+ var n = keys . Count ;
144+ var array = new TFlag [ n ] ;
145+ for ( int i = 0 ; i < n ; i ++ )
146+ array [ i ] = Converter . ConvertBackward ( flags [ 1 << i ] ) ;
166147 return array ;
167148 }
168149 }
169150
170151 /// <inheritdoc/>
171- ICollection < TFlag > IDictionary < TKey , TFlag > . Values {
172- get {
173- var list = new List < TFlag > ( keys . Count ) ;
174- for ( int i = 0 ; i < keys . Count ; i ++ ) {
175- list . Add ( converter . ConvertBackward ( flags [ 1 << i ] ) ) ;
176- }
177- return list ;
178- }
179- }
152+ IEnumerable < TFlag > IReadOnlyDictionary < TKey , TFlag > . Values => Values ;
180153
181154 #endregion
182155
183156 #region IList<KeyValuePair<TKey,TFlag>> Members
184157
185158 /// <inheritdoc/>
186- public void Add ( KeyValuePair < TKey , TFlag > item )
187- {
188- Add ( item . Key , item . Value ) ;
189- }
159+ public void Add ( KeyValuePair < TKey , TFlag > item ) => Add ( item . Key , item . Value ) ;
190160
191161 /// <inheritdoc/>
192162 public void Clear ( )
@@ -197,61 +167,35 @@ public void Clear()
197167 }
198168
199169 /// <inheritdoc/>
200- public bool Contains ( KeyValuePair < TKey , TFlag > item )
201- {
202- return ContainsKey ( item . Key ) ;
203- }
170+ public bool Contains ( KeyValuePair < TKey , TFlag > item ) => ContainsKey ( item . Key ) ;
204171
205172 /// <inheritdoc/>
206- public void CopyTo ( KeyValuePair < TKey , TFlag > [ ] array , int arrayIndex )
207- {
208- this . Copy ( array , arrayIndex ) ;
209- }
173+ public void CopyTo ( KeyValuePair < TKey , TFlag > [ ] array , int arrayIndex ) => this . Copy ( array , arrayIndex ) ;
210174
211175 /// <inheritdoc/>
212- public bool Remove ( KeyValuePair < TKey , TFlag > item )
213- {
214- return Remove ( item . Key ) ;
215- }
176+ public bool Remove ( KeyValuePair < TKey , TFlag > item ) => Remove ( item . Key ) ;
216177
217178 /// <inheritdoc/>
218- public int Count
219- {
220- [ DebuggerStepThrough ]
221- get { return keys . Count ; }
222- }
179+ public int Count => keys . Count ;
223180
224181 /// <inheritdoc/>
225- public bool IsReadOnly
226- {
227- [ DebuggerStepThrough ]
228- get { return IsLocked ; }
229- }
182+ public bool IsReadOnly => IsLocked ;
230183
231184 /// <inheritdoc/>
232- int IList < KeyValuePair < TKey , TFlag > > . IndexOf ( KeyValuePair < TKey , TFlag > item )
233- {
234- throw new NotSupportedException ( ) ;
235- }
185+ int IList < KeyValuePair < TKey , TFlag > > . IndexOf ( KeyValuePair < TKey , TFlag > item ) => throw new NotSupportedException ( ) ;
236186
237187 /// <inheritdoc/>
238- void IList < KeyValuePair < TKey , TFlag > > . Insert ( int index , KeyValuePair < TKey , TFlag > item )
239- {
240- throw new NotSupportedException ( ) ;
241- }
188+ void IList < KeyValuePair < TKey , TFlag > > . Insert ( int index , KeyValuePair < TKey , TFlag > item ) => throw new NotSupportedException ( ) ;
242189
243190 /// <inheritdoc/>
244- void IList < KeyValuePair < TKey , TFlag > > . RemoveAt ( int index )
245- {
246- throw new NotSupportedException ( ) ;
247- }
191+ void IList < KeyValuePair < TKey , TFlag > > . RemoveAt ( int index ) => throw new NotSupportedException ( ) ;
248192
249193 /// <inheritdoc/>
250194 public KeyValuePair < TKey , TFlag > this [ int index ] {
251195 get {
252196 if ( keys . Count <= index )
253197 throw new ArgumentOutOfRangeException ( "index" ) ;
254- return new KeyValuePair < TKey , TFlag > ( keys [ index ] , converter . ConvertBackward ( flags [ 1 << index ] ) ) ;
198+ return new KeyValuePair < TKey , TFlag > ( keys [ index ] , Converter . ConvertBackward ( flags [ 1 << index ] ) ) ;
255199 }
256200 set {
257201 // TODO: implement?
@@ -264,31 +208,22 @@ public KeyValuePair<TKey, TFlag> this[int index] {
264208 #region ICollection<KeyValuePair<TKey, TFlag>> Members
265209
266210 /// <inheritdoc/>
267- void ICollection < KeyValuePair < TKey , TFlag > > . Add ( KeyValuePair < TKey , TFlag > key )
268- {
269- Add ( key . Key , key . Value ) ;
270- }
211+ void ICollection < KeyValuePair < TKey , TFlag > > . Add ( KeyValuePair < TKey , TFlag > key ) => Add ( key . Key , key . Value ) ;
271212
272213 /// <inheritdoc/>
273214 bool ICollection < KeyValuePair < TKey , TFlag > > . Contains ( KeyValuePair < TKey , TFlag > item )
274215 {
275216 int index = keys . IndexOf ( item . Key ) ;
276217 if ( index < 0 )
277218 return false ;
278- return flags [ 1 << index ] == converter . ConvertForward ( item . Value ) ;
219+ return flags [ 1 << index ] == Converter . ConvertForward ( item . Value ) ;
279220 }
280221
281222 /// <inheritdoc/>
282- void ICollection < KeyValuePair < TKey , TFlag > > . CopyTo ( KeyValuePair < TKey , TFlag > [ ] array , int arrayIndex )
283- {
284- this . Copy ( array , arrayIndex ) ;
285- }
223+ void ICollection < KeyValuePair < TKey , TFlag > > . CopyTo ( KeyValuePair < TKey , TFlag > [ ] array , int arrayIndex ) => this . Copy ( array , arrayIndex ) ;
286224
287225 /// <inheritdoc/>
288- bool ICollection < KeyValuePair < TKey , TFlag > > . Remove ( KeyValuePair < TKey , TFlag > item )
289- {
290- throw new NotSupportedException ( ) ;
291- }
226+ bool ICollection < KeyValuePair < TKey , TFlag > > . Remove ( KeyValuePair < TKey , TFlag > item ) => throw new NotSupportedException ( ) ;
292227
293228 #endregion
294229
@@ -298,7 +233,7 @@ bool ICollection<KeyValuePair<TKey, TFlag>>.Remove(KeyValuePair<TKey, TFlag> ite
298233 public IEnumerator < KeyValuePair < TKey , TFlag > > GetEnumerator ( )
299234 {
300235 for ( int i = 0 ; i < keys . Count ; i ++ )
301- yield return new KeyValuePair < TKey , TFlag > ( keys [ i ] , converter . ConvertBackward ( flags [ 1 << i ] ) ) ;
236+ yield return new KeyValuePair < TKey , TFlag > ( keys [ i ] , Converter . ConvertBackward ( flags [ 1 << i ] ) ) ;
302237 }
303238
304239 /// <inheritdoc/>
@@ -314,23 +249,21 @@ IEnumerator IEnumerable.GetEnumerator()
314249 /// <inheritdoc/>
315250 public bool Equals ( FlagCollection < TKey , TFlag > other )
316251 {
252+ if ( ReferenceEquals ( this , other ) )
253+ return true ;
317254 if ( other == null )
318255 return false ;
319- if ( Count != other . Count )
256+ var count = Count ;
257+ if ( count != other . Count )
320258 return false ;
321- for ( int i = 0 ; i < Count ; i ++ )
259+ for ( int i = 0 ; i < count ; i ++ )
322260 if ( ! this [ i ] . Equals ( other [ i ] ) )
323261 return false ;
324262 return true ;
325263 }
326264
327265 /// <inheritdoc/>
328- public override bool Equals ( object obj )
329- {
330- if ( ReferenceEquals ( this , obj ) )
331- return true ;
332- return Equals ( obj as FlagCollection < TKey , TFlag > ) ;
333- }
266+ public override bool Equals ( object obj ) => obj is FlagCollection < TKey , TFlag > other && Equals ( other ) ;
334267
335268 /// <inheritdoc/>
336269 public override int GetHashCode ( ) => HashCode . Combine ( keys , flags ) ;
@@ -347,7 +280,7 @@ public override bool Equals(object obj)
347280 public FlagCollection ( Biconverter < TFlag , bool > converter )
348281 : this ( )
349282 {
350- this . converter = converter ;
283+ Converter = converter ;
351284 }
352285
353286 /// <summary>
@@ -358,15 +291,13 @@ public FlagCollection(Biconverter<TFlag, bool> converter)
358291 public FlagCollection ( Biconverter < TFlag , bool > converter , IEnumerable < KeyValuePair < TKey , TFlag > > enumerable )
359292 : this ( )
360293 {
361- this . converter = converter ;
294+ Converter = converter ;
362295 foreach ( KeyValuePair < TKey , TFlag > pair in enumerable )
363296 Add ( pair . Key , pair . Value ) ;
364297 }
365298
366299 private FlagCollection ( )
367300 {
368- keys = new List < TKey > ( ) ;
369- readOnlyKeys = keys . AsReadOnly ( ) ;
370301 }
371302
372303 #region ISerializable members
@@ -379,10 +310,9 @@ private FlagCollection()
379310 protected FlagCollection ( SerializationInfo info , StreamingContext context )
380311 : base ( info . GetBoolean ( "IsLocked" ) )
381312 {
382- converter = ( Biconverter < TFlag , bool > )
313+ Converter = ( Biconverter < TFlag , bool > )
383314 info . GetValue ( "AdvancedConverter" , typeof ( Biconverter < TFlag , bool > ) ) ;
384315 keys = ( List < TKey > ) info . GetValue ( "Keys" , typeof ( List < TKey > ) ) ;
385- readOnlyKeys = keys . AsReadOnly ( ) ;
386316 flags = new BitVector32 ( info . GetInt32 ( "Flags" ) ) ;
387317 }
388318
@@ -395,7 +325,7 @@ protected FlagCollection(SerializationInfo info, StreamingContext context)
395325 public virtual void GetObjectData ( SerializationInfo info , StreamingContext context )
396326 {
397327 info . AddValue ( "IsLocked" , IsLocked ) ;
398- info . AddValue ( "AdvancedConverter" , converter ) ;
328+ info . AddValue ( "AdvancedConverter" , Converter ) ;
399329 info . AddValue ( "Keys" , keys ) ;
400330 info . AddValue ( "Flags" , flags . Data ) ;
401331 }
0 commit comments