DynamicArray.cs

Use Concurrently or Non-Concurrently

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading;

[Serializable]
public class DynamicArray<T> : IEnumerable<T>
{
    private volatile T[]               _array;
    private volatile MonitorActionFunc _maf;
    public volatile  int               Count;
    public DynamicArray(int cap)
    {
        Count  = 0;
        _array = new T[cap];
        _maf   = new MonitorActionFunc();
    }
    public DynamicArray(IEnumerable<T> collection)
    {
        var enumerable = collection as T[] ?? collection.ToArray();
        Count  = enumerable.Length;
        _array = new T[Count];
        Array.Copy(enumerable, 0, _array, 0, Count);
        _maf = new MonitorActionFunc();
    }
    public int Length
    {
        get
        {
            var tmpThis = this;
            return tmpThis._maf.Lock(tmpThis, () => _array.Length);
        }
    }
    public T this[int index]
    {
        get
        {
            var array   = _array;
            var tmpThis = this;
            return tmpThis._maf.Lock(tmpThis, () =>
            {
                if (index > array.Length)
                    throw new Exception("Error: Index out of range.");
                return array[index];
            });
        }
        set
        {
            var tmpThis = this;
            tmpThis._maf.Lock(tmpThis, () =>
            {
                if (index > _array.Length)
                    throw new Exception("Error: Index out of range.");
                _array[index] = value;
            });
        }
    }
    IEnumerator<T> IEnumerable<T>.GetEnumerator()
    {
        return GetEnumerator();
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
    public void Resize(int newSize)
    {
        var tmpThis = this;
        tmpThis._maf.Lock(tmpThis, () =>
        {
            Array.Resize(ref _array, newSize);
        });
    }
    public void Add(T item)
    {
        var tmpThis = this;
        tmpThis._maf.Lock(tmpThis, () =>
        {
            if (Count >= _array.Length)
                throw new Exception("Item exceeds array length.");
            _array[Count] = item;
            Interlocked.Increment(ref Count);
        });
    }
    public void AddRange(IEnumerable<T> collection)
    {
        var enumerable = collection as T[] ?? collection.ToArray();
        Count  = enumerable.Length;
        _array = new T[Count];
        Array.Copy(enumerable, 0, _array, 0, Count);
    }
    public T[] ToArray()
    {
        var tmpThis = this;
        return tmpThis._maf.Lock(tmpThis, () =>
        {
            var newtArray = new T[Count];
            Array.Copy(_array, 0, newtArray, 0, Count);
            return newtArray;
        });
    }
    public void Clean()
    {
        var tmpThis = this;
        tmpThis._maf.Lock(tmpThis, () =>
        {
            var newtArray = new T[Count];
            Array.Copy(_array, 0, newtArray, 0, Count);
            _array = newtArray;
        });
    }
    public void Clear()
    {
        var tmpThis = this;
        tmpThis._maf.Lock(tmpThis, () =>
        {
            Array.Clear(_array, 0, Count);
            Count = 0;
        });
    }
    public long IndexOf(T item)
    {
        var tmpThis = this;
        return tmpThis._maf.Lock(tmpThis, () => Array.IndexOf(_array, item, 0));
    }
    public IEnumerator<T> GetEnumerator()
    {
        var tmpThis = this;
        return tmpThis._maf.Lock(tmpThis, () =>
        {
            return GetEnum();
        });
    }
    private IEnumerator<T> GetEnum()
    {
        var array = _array;
        var count = Count;
        for (var i = 0; i < count; i++)
            yield return array[i];
    }
}

Leave a Reply

Your email address will not be published. Required fields are marked *