Files
App-Installer-For-Windows-8…/DataUtils/Enumerable.cs
2026-04-06 13:09:20 +08:00

174 lines
5.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
namespace DataUtils
{
[ComVisible (true)]
[InterfaceType (ComInterfaceType.InterfaceIsDual)]
public interface _I_Enumerable: IDisposable
{
int Length { get; set; }
object this [int index] { get; set; }
void Add (object value); // push
void Push (object value);
object Pop (); // 删除并返回末尾元素
object Shift (); // 删除并返回开头元素
void Unshift (object value); // 在开头插入
void RemoveAt (int index); // 删除任意索引
void Clear (); // 清空数组
_I_Enumerable Slice (int start, int end); // 返回子数组
void Splice (int start, int deleteCount, object [] items); // 删除并插入
int IndexOf (object value); // 查找索引
bool Includes (object value); // 是否包含
void ForEach (object callback, bool suppressExceptions = false); // 遍历callback(item, index)
_I_Enumerable Concat (_I_Enumerable other); // 拼接
string Join (string separator); // 转字符串
object GetItem (int index); // 返回 { key, data } 或直接 data
void SetAt (int index, object value); // 替换元素
int IndexOfKey (int key); // 按内部 key 查找
void Move (int index, int newIndex); // 移动元素
void PushAll (object [] items); // 一次性 push 多个
object Get (int index);
object Set (int index, object value);
object At (int index);
}
public class _I_List: _I_Enumerable, IList
{
public _I_List (IEnumerable<object> initArr, bool readOnly = false, bool fixedSize = false, bool sync = true)
{
_list = initArr?.ToList () ?? new List<object> ();
IsFixedSize = fixedSize;
IsReadOnly = readOnly;
IsSynchronized = sync;
}
public _I_List (bool readOnly = false, bool fixedSize = false, bool sync = true) :
this (null, readOnly, fixedSize, sync)
{ }
protected List<object> _list;
protected object _lock = new object ();
public object this [int index] { get { return _list [index]; } set { _list [index] = value; } }
public int Count => _list.Count;
public bool IsFixedSize { get; }
public bool IsReadOnly { get; }
public bool IsSynchronized { get; }
public int Length
{
get { return _list.Count; }
set
{
if (!IsFixedSize && !IsReadOnly)
{
_list.Capacity = value;
}
}
}
public object SyncRoot => _lock;
public void Add (object value) => _list.Add (value);
public void Push (object value) => _list.Add (value);
public void RemoveAt (int index) => _list.RemoveAt (index);
public void Clear () => _list.Clear ();
public int IndexOf (object value) => _list.IndexOf (value);
int IList.Add (object value)
{
_list.Add (value);
return _list.Count - 1;
}
public bool Contains (object value) => _list.Contains (value);
public void Insert (int index, object value) => _list.Insert (index, value);
public void Remove (object value) => _list.Remove (value);
public void ForEach (object callback, bool suppressExceptions = false)
{
for (int i = 0; i < _list.Count; i++)
{
var item = _list [i];
if (suppressExceptions)
{
try { JsUtils.Call (callback, item, i); } catch { }
}
else JsUtils.Call (callback, item, i);
}
}
public IEnumerator GetEnumerator () => _list.GetEnumerator ();
public _I_Enumerable Slice (int start, int end)
{
if (end < 0) end = _list.Count + end;
start = Math.Max (0, start);
end = Math.Min (_list.Count, end);
var arr = _list.GetRange (start, Math.Max (0, end - start));
return new _I_List (arr);
}
public void Splice (int start, int deleteCount, object [] items)
{
if (start < 0) start = Math.Max (0, _list.Count + start);
int count = Math.Min (deleteCount, _list.Count - start);
_list.RemoveRange (start, count);
if (items != null && items.Length > 0)
_list.InsertRange (start, items);
}
public bool Includes (object value) => _list.Contains (value);
public _I_Enumerable Concat (_I_Enumerable other)
{
var newList = new List<object> (_list);
if (other is _I_List)
newList.AddRange ((other as _I_List)._list);
return new _I_List (newList);
}
public string Join (string separator)
{
return string.Join (separator ?? ",", _list.Select (x => x?.ToString () ?? ""));
}
public object GetItem (int index) => _list [index];
public void SetAt (int index, object value) => _list [index] = value;
public int IndexOfKey (int key)
{
return key >= 0 && key < _list.Count ? key : -1;
}
public void Move (int index, int newIndex)
{
if (index < 0 || index >= _list.Count || newIndex < 0 || newIndex >= _list.Count) return;
var item = _list [index];
_list.RemoveAt (index);
_list.Insert (newIndex, item);
}
public void PushAll (object [] items)
{
if (items == null || items.Length == 0) return;
_list.AddRange (items);
}
public void CopyTo (Array array, int index)
{
if (array == null) throw new ArgumentNullException (nameof (array));
for (int i = 0; i < _list.Count && index + i < array.Length; i++)
array.SetValue (_list [i], index + i);
}
public object Pop ()
{
if (_list.Count == 0) return null;
var last = _list [_list.Count - 1];
_list.RemoveAt (_list.Count - 1);
return last;
}
public object Shift ()
{
if (_list.Count == 0) return null;
var first = _list [0];
_list.RemoveAt (0);
return first;
}
public void Unshift (object value) => _list.Insert (0, value);
public void Dispose ()
{
_list?.Clear ();
_list = null;
}
public object Get (int index) => this [index];
public object Set (int index, object value) => this [index] = value;
public object At (int index) => this [index];
}
}