Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(215)

Side by Side Diff: third_party/protobuf/csharp/src/Google.Protobuf/Collections/MapField.cs

Issue 1983203003: Update third_party/protobuf to protobuf-v3.0.0-beta-3 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix compile error Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 #region Copyright notice and license 1 #region Copyright notice and license
2 // Protocol Buffers - Google's data interchange format 2 // Protocol Buffers - Google's data interchange format
3 // Copyright 2015 Google Inc. All rights reserved. 3 // Copyright 2015 Google Inc. All rights reserved.
4 // https://developers.google.com/protocol-buffers/ 4 // https://developers.google.com/protocol-buffers/
5 // 5 //
6 // Redistribution and use in source and binary forms, with or without 6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are 7 // modification, are permitted provided that the following conditions are
8 // met: 8 // met:
9 // 9 //
10 // * Redistributions of source code must retain the above copyright 10 // * Redistributions of source code must retain the above copyright
(...skipping 16 matching lines...) Expand all
27 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #endregion 31 #endregion
32 32
33 using Google.Protobuf.Reflection; 33 using Google.Protobuf.Reflection;
34 using System; 34 using System;
35 using System.Collections; 35 using System.Collections;
36 using System.Collections.Generic; 36 using System.Collections.Generic;
37 using System.IO;
37 using System.Linq; 38 using System.Linq;
38 using System.Text; 39 using System.Text;
39 using Google.Protobuf.Compatibility; 40 using Google.Protobuf.Compatibility;
40 41
41 namespace Google.Protobuf.Collections 42 namespace Google.Protobuf.Collections
42 { 43 {
43 /// <summary> 44 /// <summary>
44 /// Representation of a map field in a Protocol Buffer message. 45 /// Representation of a map field in a Protocol Buffer message.
45 /// </summary> 46 /// </summary>
46 /// <typeparam name="TKey">Key type in the map. Must be a type supported by Protocol Buffer map keys.</typeparam> 47 /// <typeparam name="TKey">Key type in the map. Must be a type supported by Protocol Buffer map keys.</typeparam>
47 /// <typeparam name="TValue">Value type in the map. Must be a type supported by Protocol Buffers.</typeparam> 48 /// <typeparam name="TValue">Value type in the map. Must be a type supported by Protocol Buffers.</typeparam>
48 /// <remarks> 49 /// <remarks>
49 /// <para> 50 /// <para>
50 /// This implementation preserves insertion order for simplicity of testing 51 /// This implementation preserves insertion order for simplicity of testing
51 /// code using maps fields. Overwriting an existing entry does not change th e 52 /// code using maps fields. Overwriting an existing entry does not change th e
52 /// position of that entry within the map. Equality is not order-sensitive. 53 /// position of that entry within the map. Equality is not order-sensitive.
53 /// For string keys, the equality comparison is provided by <see cref="Strin gComparer.Ordinal" />. 54 /// For string keys, the equality comparison is provided by <see cref="Strin gComparer.Ordinal" />.
54 /// </para> 55 /// </para>
55 /// <para> 56 /// <para>
57 /// Null values are not permitted in the map, either for wrapper types or re gular messages.
58 /// If a map is deserialized from a data stream and the value is missing fro m an entry, a default value
59 /// is created instead. For primitive types, that is the regular default val ue (0, the empty string and so
60 /// on); for message types, an empty instance of the message is created, as if the map entry contained a 0-length
61 /// encoded value for the field.
62 /// </para>
63 /// <para>
56 /// This implementation does not generally prohibit the use of key/value typ es which are not 64 /// This implementation does not generally prohibit the use of key/value typ es which are not
57 /// supported by Protocol Buffers (e.g. using a key type of <code>byte</code >) but nor does it guarantee 65 /// supported by Protocol Buffers (e.g. using a key type of <code>byte</code >) but nor does it guarantee
58 /// that all operations will work in such cases. 66 /// that all operations will work in such cases.
59 /// </para> 67 /// </para>
60 /// </remarks> 68 /// </remarks>
61 public sealed class MapField<TKey, TValue> : IDeepCloneable<MapField<TKey, T Value>>, IDictionary<TKey, TValue>, IEquatable<MapField<TKey, TValue>>, IDiction ary 69 public sealed class MapField<TKey, TValue> : IDeepCloneable<MapField<TKey, T Value>>, IDictionary<TKey, TValue>, IEquatable<MapField<TKey, TValue>>, IDiction ary
62 { 70 {
63 // TODO: Don't create the map/list until we have an entry. (Assume many maps will be empty.) 71 // TODO: Don't create the map/list until we have an entry. (Assume many maps will be empty.)
64 private readonly bool allowNullValues;
65 private readonly Dictionary<TKey, LinkedListNode<KeyValuePair<TKey, TVal ue>>> map = 72 private readonly Dictionary<TKey, LinkedListNode<KeyValuePair<TKey, TVal ue>>> map =
66 new Dictionary<TKey, LinkedListNode<KeyValuePair<TKey, TValue>>>(); 73 new Dictionary<TKey, LinkedListNode<KeyValuePair<TKey, TValue>>>();
67 private readonly LinkedList<KeyValuePair<TKey, TValue>> list = new Linke dList<KeyValuePair<TKey, TValue>>(); 74 private readonly LinkedList<KeyValuePair<TKey, TValue>> list = new Linke dList<KeyValuePair<TKey, TValue>>();
68 75
69 /// <summary> 76 /// <summary>
70 /// Constructs a new map field, defaulting the value nullability to only allow null values for message types
71 /// and non-nullable value types.
72 /// </summary>
73 public MapField() : this(typeof(IMessage).IsAssignableFrom(typeof(TValue )) || Nullable.GetUnderlyingType(typeof(TValue)) != null)
74 {
75 }
76
77 /// <summary>
78 /// Constructs a new map field, overriding the choice of whether null va lues are permitted in the map.
79 /// This is used by wrapper types, where maps with string and bytes wrap pers as the value types
80 /// support null values.
81 /// </summary>
82 /// <param name="allowNullValues">Whether null values are permitted in t he map or not.</param>
83 public MapField(bool allowNullValues)
84 {
85 if (allowNullValues && typeof(TValue).IsValueType() && Nullable.GetU nderlyingType(typeof(TValue)) == null)
86 {
87 throw new ArgumentException("allowNullValues", "Non-nullable val ue types do not support null values");
88 }
89 this.allowNullValues = allowNullValues;
90 }
91
92 /// <summary>
93 /// Creates a deep clone of this object. 77 /// Creates a deep clone of this object.
94 /// </summary> 78 /// </summary>
95 /// <returns> 79 /// <returns>
96 /// A deep clone of this object. 80 /// A deep clone of this object.
97 /// </returns> 81 /// </returns>
98 public MapField<TKey, TValue> Clone() 82 public MapField<TKey, TValue> Clone()
99 { 83 {
100 var clone = new MapField<TKey, TValue>(allowNullValues); 84 var clone = new MapField<TKey, TValue>();
101 // Keys are never cloneable. Values might be. 85 // Keys are never cloneable. Values might be.
102 if (typeof(IDeepCloneable<TValue>).IsAssignableFrom(typeof(TValue))) 86 if (typeof(IDeepCloneable<TValue>).IsAssignableFrom(typeof(TValue)))
103 { 87 {
104 foreach (var pair in list) 88 foreach (var pair in list)
105 { 89 {
106 clone.Add(pair.Key, pair.Value == null ? pair.Value : ((IDee pCloneable<TValue>)pair.Value).Clone()); 90 clone.Add(pair.Key, ((IDeepCloneable<TValue>)pair.Value).Clo ne());
107 } 91 }
108 } 92 }
109 else 93 else
110 { 94 {
111 // Nothing is cloneable, so we don't need to worry. 95 // Nothing is cloneable, so we don't need to worry.
112 clone.Add(this); 96 clone.Add(this);
113 } 97 }
114 return clone; 98 return clone;
115 } 99 }
116 100
(...skipping 16 matching lines...) Expand all
133 this[key] = value; 117 this[key] = value;
134 } 118 }
135 119
136 /// <summary> 120 /// <summary>
137 /// Determines whether the specified key is present in the map. 121 /// Determines whether the specified key is present in the map.
138 /// </summary> 122 /// </summary>
139 /// <param name="key">The key to check.</param> 123 /// <param name="key">The key to check.</param>
140 /// <returns><c>true</c> if the map contains the given key; <c>false</c> otherwise.</returns> 124 /// <returns><c>true</c> if the map contains the given key; <c>false</c> otherwise.</returns>
141 public bool ContainsKey(TKey key) 125 public bool ContainsKey(TKey key)
142 { 126 {
143 Preconditions.CheckNotNullUnconstrained(key, "key"); 127 ProtoPreconditions.CheckNotNullUnconstrained(key, "key");
144 return map.ContainsKey(key); 128 return map.ContainsKey(key);
145 } 129 }
146 130
147 private bool ContainsValue(TValue value) 131 private bool ContainsValue(TValue value)
148 { 132 {
149 var comparer = EqualityComparer<TValue>.Default; 133 var comparer = EqualityComparer<TValue>.Default;
150 return list.Any(pair => comparer.Equals(pair.Value, value)); 134 return list.Any(pair => comparer.Equals(pair.Value, value));
151 } 135 }
152 136
153 /// <summary> 137 /// <summary>
154 /// Removes the entry identified by the given key from the map. 138 /// Removes the entry identified by the given key from the map.
155 /// </summary> 139 /// </summary>
156 /// <param name="key">The key indicating the entry to remove from the ma p.</param> 140 /// <param name="key">The key indicating the entry to remove from the ma p.</param>
157 /// <returns><c>true</c> if the map contained the given key before the e ntry was removed; <c>false</c> otherwise.</returns> 141 /// <returns><c>true</c> if the map contained the given key before the e ntry was removed; <c>false</c> otherwise.</returns>
158 public bool Remove(TKey key) 142 public bool Remove(TKey key)
159 { 143 {
160 Preconditions.CheckNotNullUnconstrained(key, "key"); 144 ProtoPreconditions.CheckNotNullUnconstrained(key, "key");
161 LinkedListNode<KeyValuePair<TKey, TValue>> node; 145 LinkedListNode<KeyValuePair<TKey, TValue>> node;
162 if (map.TryGetValue(key, out node)) 146 if (map.TryGetValue(key, out node))
163 { 147 {
164 map.Remove(key); 148 map.Remove(key);
165 node.List.Remove(node); 149 node.List.Remove(node);
166 return true; 150 return true;
167 } 151 }
168 else 152 else
169 { 153 {
170 return false; 154 return false;
(...skipping 27 matching lines...) Expand all
198 /// Gets or sets the value associated with the specified key. 182 /// Gets or sets the value associated with the specified key.
199 /// </summary> 183 /// </summary>
200 /// <param name="key">The key of the value to get or set.</param> 184 /// <param name="key">The key of the value to get or set.</param>
201 /// <exception cref="KeyNotFoundException">The property is retrieved and key does not exist in the collection.</exception> 185 /// <exception cref="KeyNotFoundException">The property is retrieved and key does not exist in the collection.</exception>
202 /// <returns>The value associated with the specified key. If the specifi ed key is not found, 186 /// <returns>The value associated with the specified key. If the specifi ed key is not found,
203 /// a get operation throws a <see cref="KeyNotFoundException"/>, and a s et operation creates a new element with the specified key.</returns> 187 /// a get operation throws a <see cref="KeyNotFoundException"/>, and a s et operation creates a new element with the specified key.</returns>
204 public TValue this[TKey key] 188 public TValue this[TKey key]
205 { 189 {
206 get 190 get
207 { 191 {
208 Preconditions.CheckNotNullUnconstrained(key, "key"); 192 ProtoPreconditions.CheckNotNullUnconstrained(key, "key");
209 TValue value; 193 TValue value;
210 if (TryGetValue(key, out value)) 194 if (TryGetValue(key, out value))
211 { 195 {
212 return value; 196 return value;
213 } 197 }
214 throw new KeyNotFoundException(); 198 throw new KeyNotFoundException();
215 } 199 }
216 set 200 set
217 { 201 {
218 Preconditions.CheckNotNullUnconstrained(key, "key"); 202 ProtoPreconditions.CheckNotNullUnconstrained(key, "key");
219 // value == null check here is redundant, but avoids boxing. 203 // value == null check here is redundant, but avoids boxing.
220 if (value == null && !allowNullValues) 204 if (value == null)
221 { 205 {
222 Preconditions.CheckNotNullUnconstrained(value, "value"); 206 ProtoPreconditions.CheckNotNullUnconstrained(value, "value") ;
223 } 207 }
224 LinkedListNode<KeyValuePair<TKey, TValue>> node; 208 LinkedListNode<KeyValuePair<TKey, TValue>> node;
225 var pair = new KeyValuePair<TKey, TValue>(key, value); 209 var pair = new KeyValuePair<TKey, TValue>(key, value);
226 if (map.TryGetValue(key, out node)) 210 if (map.TryGetValue(key, out node))
227 { 211 {
228 node.Value = pair; 212 node.Value = pair;
229 } 213 }
230 else 214 else
231 { 215 {
232 node = list.AddLast(pair); 216 node = list.AddLast(pair);
233 map[key] = node; 217 map[key] = node;
234 } 218 }
235 } 219 }
236 } 220 }
237 221
238 /// <summary> 222 /// <summary>
239 /// Gets a collection containing the keys in the map. 223 /// Gets a collection containing the keys in the map.
240 /// </summary> 224 /// </summary>
241 public ICollection<TKey> Keys { get { return new MapView<TKey>(this, pai r => pair.Key, ContainsKey); } } 225 public ICollection<TKey> Keys { get { return new MapView<TKey>(this, pai r => pair.Key, ContainsKey); } }
242 226
243 /// <summary> 227 /// <summary>
244 /// Gets a collection containing the values in the map. 228 /// Gets a collection containing the values in the map.
245 /// </summary> 229 /// </summary>
246 public ICollection<TValue> Values { get { return new MapView<TValue>(thi s, pair => pair.Value, ContainsValue); } } 230 public ICollection<TValue> Values { get { return new MapView<TValue>(thi s, pair => pair.Value, ContainsValue); } }
247 231
248 /// <summary> 232 /// <summary>
249 /// Adds the specified entries to the map. 233 /// Adds the specified entries to the map. The keys and values are not a utomatically cloned.
250 /// </summary> 234 /// </summary>
251 /// <param name="entries">The entries to add to the map.</param> 235 /// <param name="entries">The entries to add to the map.</param>
252 public void Add(IDictionary<TKey, TValue> entries) 236 public void Add(IDictionary<TKey, TValue> entries)
253 { 237 {
254 Preconditions.CheckNotNull(entries, "entries"); 238 ProtoPreconditions.CheckNotNull(entries, "entries");
255 foreach (var pair in entries) 239 foreach (var pair in entries)
256 { 240 {
257 Add(pair.Key, pair.Value); 241 Add(pair.Key, pair.Value);
258 } 242 }
259 } 243 }
260 244
261 /// <summary> 245 /// <summary>
262 /// Returns an enumerator that iterates through the collection. 246 /// Returns an enumerator that iterates through the collection.
263 /// </summary> 247 /// </summary>
264 /// <returns> 248 /// <returns>
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 node.List.Remove(node); 324 node.List.Remove(node);
341 return true; 325 return true;
342 } 326 }
343 else 327 else
344 { 328 {
345 return false; 329 return false;
346 } 330 }
347 } 331 }
348 332
349 /// <summary> 333 /// <summary>
350 /// Returns whether or not this map allows values to be null.
351 /// </summary>
352 public bool AllowsNullValues { get { return allowNullValues; } }
353
354 /// <summary>
355 /// Gets the number of elements contained in the map. 334 /// Gets the number of elements contained in the map.
356 /// </summary> 335 /// </summary>
357 public int Count { get { return list.Count; } } 336 public int Count { get { return list.Count; } }
358 337
359 /// <summary> 338 /// <summary>
360 /// Gets a value indicating whether the map is read-only. 339 /// Gets a value indicating whether the map is read-only.
361 /// </summary> 340 /// </summary>
362 public bool IsReadOnly { get { return false; } } 341 public bool IsReadOnly { get { return false; } }
363 342
364 /// <summary> 343 /// <summary>
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
489 } 468 }
490 return size; 469 return size;
491 } 470 }
492 471
493 /// <summary> 472 /// <summary>
494 /// Returns a string representation of this repeated field, in the same 473 /// Returns a string representation of this repeated field, in the same
495 /// way as it would be represented by the default JSON formatter. 474 /// way as it would be represented by the default JSON formatter.
496 /// </summary> 475 /// </summary>
497 public override string ToString() 476 public override string ToString()
498 { 477 {
499 var builder = new StringBuilder(); 478 var writer = new StringWriter();
500 JsonFormatter.Default.WriteDictionary(builder, this); 479 JsonFormatter.Default.WriteDictionary(writer, this);
501 return builder.ToString(); 480 return writer.ToString();
502 } 481 }
503 482
504 #region IDictionary explicit interface implementation 483 #region IDictionary explicit interface implementation
505 void IDictionary.Add(object key, object value) 484 void IDictionary.Add(object key, object value)
506 { 485 {
507 Add((TKey)key, (TValue)value); 486 Add((TKey)key, (TValue)value);
508 } 487 }
509 488
510 bool IDictionary.Contains(object key) 489 bool IDictionary.Contains(object key)
511 { 490 {
512 if (!(key is TKey)) 491 if (!(key is TKey))
513 { 492 {
514 return false; 493 return false;
515 } 494 }
516 return ContainsKey((TKey)key); 495 return ContainsKey((TKey)key);
517 } 496 }
518 497
519 IDictionaryEnumerator IDictionary.GetEnumerator() 498 IDictionaryEnumerator IDictionary.GetEnumerator()
520 { 499 {
521 return new DictionaryEnumerator(GetEnumerator()); 500 return new DictionaryEnumerator(GetEnumerator());
522 } 501 }
523 502
524 void IDictionary.Remove(object key) 503 void IDictionary.Remove(object key)
525 { 504 {
526 Preconditions.CheckNotNull(key, "key"); 505 ProtoPreconditions.CheckNotNull(key, "key");
527 if (!(key is TKey)) 506 if (!(key is TKey))
528 { 507 {
529 return; 508 return;
530 } 509 }
531 Remove((TKey)key); 510 Remove((TKey)key);
532 } 511 }
533 512
534 void ICollection.CopyTo(Array array, int index) 513 void ICollection.CopyTo(Array array, int index)
535 { 514 {
536 // This is ugly and slow as heck, but with any luck it will never be used anyway. 515 // This is ugly and slow as heck, but with any luck it will never be used anyway.
537 ICollection temp = this.Select(pair => new DictionaryEntry(pair.Key, pair.Value)).ToList(); 516 ICollection temp = this.Select(pair => new DictionaryEntry(pair.Key, pair.Value)).ToList();
538 temp.CopyTo(array, index); 517 temp.CopyTo(array, index);
539 } 518 }
540 519
541 bool IDictionary.IsFixedSize { get { return false; } } 520 bool IDictionary.IsFixedSize { get { return false; } }
542 521
543 ICollection IDictionary.Keys { get { return (ICollection)Keys; } } 522 ICollection IDictionary.Keys { get { return (ICollection)Keys; } }
544 523
545 ICollection IDictionary.Values { get { return (ICollection)Values; } } 524 ICollection IDictionary.Values { get { return (ICollection)Values; } }
546 525
547 bool ICollection.IsSynchronized { get { return false; } } 526 bool ICollection.IsSynchronized { get { return false; } }
548 527
549 object ICollection.SyncRoot { get { return this; } } 528 object ICollection.SyncRoot { get { return this; } }
550 529
551 object IDictionary.this[object key] 530 object IDictionary.this[object key]
552 { 531 {
553 get 532 get
554 { 533 {
555 Preconditions.CheckNotNull(key, "key"); 534 ProtoPreconditions.CheckNotNull(key, "key");
556 if (!(key is TKey)) 535 if (!(key is TKey))
557 { 536 {
558 return null; 537 return null;
559 } 538 }
560 TValue value; 539 TValue value;
561 TryGetValue((TKey)key, out value); 540 TryGetValue((TKey)key, out value);
562 return value; 541 return value;
563 } 542 }
564 543
565 set 544 set
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
625 604
626 /// <summary> 605 /// <summary>
627 /// A mutable message class, used for parsing and serializing. This 606 /// A mutable message class, used for parsing and serializing. This
628 /// delegates the work to a codec, but implements the <see cref="IMe ssage"/> interface 607 /// delegates the work to a codec, but implements the <see cref="IMe ssage"/> interface
629 /// for interop with <see cref="CodedInputStream"/> and <see cref="C odedOutputStream"/>. 608 /// for interop with <see cref="CodedInputStream"/> and <see cref="C odedOutputStream"/>.
630 /// This is nested inside Codec as it's tightly coupled to the assoc iated codec, 609 /// This is nested inside Codec as it's tightly coupled to the assoc iated codec,
631 /// and it's simpler if it has direct access to all its fields. 610 /// and it's simpler if it has direct access to all its fields.
632 /// </summary> 611 /// </summary>
633 internal class MessageAdapter : IMessage 612 internal class MessageAdapter : IMessage
634 { 613 {
614 private static readonly byte[] ZeroLengthMessageStreamData = new byte[] { 0 };
615
635 private readonly Codec codec; 616 private readonly Codec codec;
636 internal TKey Key { get; set; } 617 internal TKey Key { get; set; }
637 internal TValue Value { get; set; } 618 internal TValue Value { get; set; }
638 619
639 internal MessageAdapter(Codec codec) 620 internal MessageAdapter(Codec codec)
640 { 621 {
641 this.codec = codec; 622 this.codec = codec;
642 } 623 }
643 624
644 internal void Reset() 625 internal void Reset()
(...skipping 13 matching lines...) Expand all
658 } 639 }
659 else if (tag == codec.valueCodec.Tag) 640 else if (tag == codec.valueCodec.Tag)
660 { 641 {
661 Value = codec.valueCodec.Read(input); 642 Value = codec.valueCodec.Read(input);
662 } 643 }
663 else 644 else
664 { 645 {
665 input.SkipLastField(); 646 input.SkipLastField();
666 } 647 }
667 } 648 }
649
650 // Corner case: a map entry with a key but no value, where t he value type is a message.
651 // Read it as if we'd seen an input stream with no data (i.e . create a "default" message).
652 if (Value == null)
653 {
654 Value = codec.valueCodec.Read(new CodedInputStream(ZeroL engthMessageStreamData));
655 }
668 } 656 }
669 657
670 public void WriteTo(CodedOutputStream output) 658 public void WriteTo(CodedOutputStream output)
671 { 659 {
672 codec.keyCodec.WriteTagAndValue(output, Key); 660 codec.keyCodec.WriteTagAndValue(output, Key);
673 codec.valueCodec.WriteTagAndValue(output, Value); 661 codec.valueCodec.WriteTagAndValue(output, Value);
674 } 662 }
675 663
676 public int CalculateSize() 664 public int CalculateSize()
677 { 665 {
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
763 throw new ArgumentException("Not enough space in the array", "array"); 751 throw new ArgumentException("Not enough space in the array", "array");
764 } 752 }
765 foreach (var item in this) 753 foreach (var item in this)
766 { 754 {
767 array.SetValue(item, index++); 755 array.SetValue(item, index++);
768 } 756 }
769 } 757 }
770 } 758 }
771 } 759 }
772 } 760 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698