Fix IDE0025 (use expression body for properties)
[mono-project.git] / netcore / System.Private.CoreLib / shared / System / Collections / ObjectModel / ReadOnlyCollection.cs
blob9a9a14291768da102a21239c05efc32e190fe6ef
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
5 using System.Collections.Generic;
6 using System.Diagnostics;
8 namespace System.Collections.ObjectModel
10 [Serializable]
11 [DebuggerTypeProxy(typeof(ICollectionDebugView<>))]
12 [DebuggerDisplay("Count = {Count}")]
13 [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
14 public class ReadOnlyCollection<T> : IList<T>, IList, IReadOnlyList<T>
16 private readonly IList<T> list; // Do not rename (binary serialization)
18 public ReadOnlyCollection(IList<T> list)
20 if (list == null)
22 ThrowHelper.ThrowArgumentNullException(ExceptionArgument.list);
24 this.list = list;
27 public int Count => list.Count;
29 public T this[int index]
31 get { return list[index]; }
34 public bool Contains(T value)
36 return list.Contains(value);
39 public void CopyTo(T[] array, int index)
41 list.CopyTo(array, index);
44 public IEnumerator<T> GetEnumerator()
46 return list.GetEnumerator();
49 public int IndexOf(T value)
51 return list.IndexOf(value);
54 protected IList<T> Items => list;
56 bool ICollection<T>.IsReadOnly => true;
58 T IList<T>.this[int index]
60 get { return list[index]; }
61 set
63 ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
67 void ICollection<T>.Add(T value)
69 ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
72 void ICollection<T>.Clear()
74 ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
77 void IList<T>.Insert(int index, T value)
79 ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
82 bool ICollection<T>.Remove(T value)
84 ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
85 return false;
88 void IList<T>.RemoveAt(int index)
90 ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
93 IEnumerator IEnumerable.GetEnumerator()
95 return ((IEnumerable)list).GetEnumerator();
98 bool ICollection.IsSynchronized => false;
100 object ICollection.SyncRoot => list is ICollection coll ? coll.SyncRoot : this;
102 void ICollection.CopyTo(Array array, int index)
104 if (array == null)
106 ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
109 if (array.Rank != 1)
111 ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RankMultiDimNotSupported);
114 if (array.GetLowerBound(0) != 0)
116 ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_NonZeroLowerBound);
119 if (index < 0)
121 ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
124 if (array.Length - index < Count)
126 ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
129 if (array is T[] items)
131 list.CopyTo(items, index);
133 else
136 // Catch the obvious case assignment will fail.
137 // We can't find all possible problems by doing the check though.
138 // For example, if the element type of the Array is derived from T,
139 // we can't figure out if we can successfully copy the element beforehand.
141 Type targetType = array.GetType().GetElementType()!;
142 Type sourceType = typeof(T);
143 if (!(targetType.IsAssignableFrom(sourceType) || sourceType.IsAssignableFrom(targetType)))
145 ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
149 // We can't cast array of value type to object[], so we don't support
150 // widening of primitive types here.
152 object?[]? objects = array as object[];
153 if (objects == null)
155 ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
158 int count = list.Count;
161 for (int i = 0; i < count; i++)
163 objects[index++] = list[i];
166 catch (ArrayTypeMismatchException)
168 ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
173 bool IList.IsFixedSize => true;
175 bool IList.IsReadOnly => true;
177 object? IList.this[int index]
179 get { return list[index]; }
182 ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
186 int IList.Add(object? value)
188 ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
189 return -1;
192 void IList.Clear()
194 ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
197 private static bool IsCompatibleObject(object? value)
199 // Non-null values are fine. Only accept nulls if T is a class or Nullable<U>.
200 // Note that default(T) is not equal to null for value types except when T is Nullable<U>.
201 return ((value is T) || (value == null && default(T)! == null));
204 bool IList.Contains(object? value)
206 if (IsCompatibleObject(value))
208 return Contains((T)value!);
210 return false;
213 int IList.IndexOf(object? value)
215 if (IsCompatibleObject(value))
217 return IndexOf((T)value!);
219 return -1;
222 void IList.Insert(int index, object? value)
224 ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
227 void IList.Remove(object? value)
229 ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
232 void IList.RemoveAt(int index)
234 ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);