You probably know the following problem: you want to share the collection between two objects A and B (or in the same way you want to open the collection using a property) and ... well, you understand that this is actually not a good idea since A and B can then modify the collection and blah blah armageddon now ...
But often you realize that you donβt want to share the collection as a whole, but you want to initialize the object only with the elements of the collection or pass the elements to the method of the object. In addition, the elements of the object do not change during the life of the object, so you often do such things:
public class Foo
{
private List<int> items;
public Foo(IEnumerable<int> items)
{
this.items = items.ToList();
}
public ReadOnlyCollection<int> Items
{
get { return new ReadOnlyCollection(this.items); }
}
}
.ToList() ReadonlyCollection-Wrapper , :.ToList() , x , ReadOnlyCollection , , , .
, , , (: 80 - 90%), , ( : ). , : - , , , /, .
: - () ?
Btw: , Sequence ,
) ( )
b) , .net
c) , , .
public sealed class Sequence<T> : IEnumerable<T>
{
private readonly T[] items;
public Sequence(IEnumerable<T> items)
{
this.items = items.ToArray();
}
public Sequence(int size, Func<int, T> producer)
{
this.items = new T[size];
for (int i = 0; i < size; i++)
{
this.items[i] = producer(i);
}
}
public T this[int i]
{
get { return this.items[i]; }
}
public int Length
{
get { return this.items.Length; }
}
public bool Contains(T item)
{
for (int i = 0; i < this.items.Length; i++)
{
if (this.items[i].Equals(item))
return true;
}
return false;
}
public Enumerator<T> GetEnumerator()
{
return new Enumerator<T>(this);
}
IEnumerator<T> System.Collections.Generic.IEnumerable<T>.GetEnumerator()
{
return GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public struct Enumerator<T> : IEnumerator<T>
{
private T[] items;
private int nextIndex;
private T current;
internal Enumerator(Sequence<T> immutableArray)
{
this.items = immutableArray.items;
this.nextIndex = 0;
this.current = default(T);
}
public T Current
{
get { return this.current; }
}
object System.Collections.IEnumerator.Current
{
get { return this.Current; }
}
public void Dispose()
{
}
public bool MoveNext()
{
if (this.nextIndex < this.items.Length)
{
this.current = this.items[this.nextIndex];
this.nextIndex++;
return true;
}
else
{
return false;
}
}
public void Reset()
{
this.nextIndex = 0;
this.current = default(T);
}
}
}