写了一个超级吃内存的“疯狂数据库”。用空间换时间。
本集合可以拓展一下作为一个泛型List使用。适用于引索常量对象。
并发List(ConcurrentList)集合依赖于开源项目:
https://github.com/azborgonovo/SlimConcurrentCollections
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using SlimConcurrentCollections;
namespace Inspector_For_Test_Sieves.Model.Entities
{
///
/// 专门用于存储偏向常量、字段类型独立不重复的数据,提供高效查询。
/// 偏向只增不减。(非线程安全)
///
public class CrazyAddOnlyDatabase : IEnumerable where T : class
{
public class ReadWriteMethod
{
public const string GetValueMethodName = "GetValue";
public const string SetValueMethodName = "SetValue";
public static readonly Type[] GetValueMethodParams = {typeof(object)};
public static readonly Type[] SetValueMethodParams = {typeof(object), typeof(object)};
public static readonly MethodInfo FieldInfoRead =
typeof(FieldInfo).GetMethod(GetValueMethodName, GetValueMethodParams);
public static readonly MethodInfo FieldInfoWrite =
typeof(FieldInfo).GetMethod(SetValueMethodName, SetValueMethodParams);
public static readonly MethodInfo PropertyInfoRead =
typeof(PropertyInfo).GetMethod(GetValueMethodName, GetValueMethodParams);
public static readonly MethodInfo PropertyInfoWrite =
typeof(PropertyInfo).GetMethod(SetValueMethodName, SetValueMethodParams);
protected object MethodProvider;
protected MethodInfo ReadMethod;
protected MethodInfo WriteMethod;
public object Read(object operationTarget)
{
return ReadMethod.Invoke(MethodProvider, new[] {operationTarget});
}
public object Write(object operationTarget, object inputValue)
{
return WriteMethod.Invoke(MethodProvider, new[] {operationTarget, inputValue});
}
public ReadWriteMethod(FieldInfo fieldInfo)
{
MethodProvider = fieldInfo;
ReadMethod = FieldInfoRead;
WriteMethod = FieldInfoWrite;
}
public ReadWriteMethod(PropertyInfo propertyInfo)
{
MethodProvider = propertyInfo;
ReadMethod = PropertyInfoRead;
WriteMethod = PropertyInfoWrite;
}
}
///
/// 记录每一列的类型(有序)
///
protected List MyColumnTypeList = new List();
///
/// 记录每一列的反射类型(有序)
///
protected List MemberInfoList = new List();
///
/// 记录每一列的读写方法(有序)
///
protected List MethodInfoList = new List();
///
/// 记录每一列的类型 的 字段名称(有序)
///
protected List MyColumnNameList = new List();
///
/// 每一列的引索。以对象里的每一个字段的值作为 键,值 是 行下标。
///
protected List>> RowIndexDatabase =
new List>>();
///
/// 记录每一行的对象
///
protected ConcurrentList RowList = new ConcurrentList();
// ///
// /// 记录主键列(不允许重复)
// ///
// protected Dictionary PrimaryKeyColumn = new Dictionary();
///
/// 字段名称做主键,加速引索查询
///
protected IDictionary ColumnNameListCache = new Dictionary();
///
/// Type 字段做主键,加速引索查询。
/// (注意!这只会引索到同类型的其中一个!
/// 最好是在类型不重复的情况下使用)
///
protected IDictionary ColumnTypeListCache = new Dictionary();
///
/// C#泛型如果不是class类型则无法使用“as”关键词来无损拆箱。
/// 为了克服泛型支持性不佳而使用反射强行调用
///
protected MethodInfo MethodInfoGetListByColumnWithClassType;
///
/// 是否为字段值为 null 的 字段 添加引索
///
public bool NoIndex4Null { get; set; }
public IReadOnlyList ColumnTypeList => MyColumnTypeList.AsReadOnly();
public IReadOnlyList ColumnNameList => MyColumnNameList.AsReadOnly();
public System.Collections.ObjectModel.ReadOnlyDictionary ColumnNameDictionary =>
new System.Collections.ObjectModel.ReadOnlyDictionary(ColumnNameListCache);
public System.Collections.ObjectModel.ReadOnlyDictionary ColumnTypeDictionary =>
new System.Collections.ObjectModel.ReadOnlyDictionary(ColumnTypeListCache);
public CrazyAddOnlyDatabase() : this(false)
{
}
public CrazyAddOnlyDatabase(bool noIndex4Null) :
this(BindingFlags.Instance | BindingFlags.Public, noIndex4Null)
{
}
public CrazyAddOnlyDatabase(BindingFlags bindingAttr, bool noIndex4Null)
{
MethodInfoGetListByColumnWithClassType = this.GetType().GetMethod(
nameof(GetListByColumnWithClassType)
);
Type type = typeof(T);
PropertyInfo[] propertyInfos = type.GetProperties(bindingAttr);
FieldInfo[] fieldInfos = type.GetFields(bindingAttr);
NoIndex4Null = noIndex4Null;
int column = 0;
for (int j = 0; j < propertyInfos.Length; j++, column++)
{
PropertyInfo propertyInfo = propertyInfos[j];
MemberInfoList.Add(propertyInfo);
MethodInfoList.Add(new ReadWriteMethod(propertyInfo));
MyColumnTypeList.Add(propertyInfo.PropertyType);
MyColumnNameList.Add(propertyInfo.Name);
ColumnNameListCache[propertyInfo.Name] = column;
ColumnTypeListCache[propertyInfo.PropertyType] = column;
RowIndexDatabase.Add(new ConcurrentDictionary 


