【发布时间】:2020-09-25 06:05:38
【问题描述】:
我正在针对内存状态树实现自定义数据存储,但我的索引遇到了一些问题。我的索引是用来覆盖的,所以它们应该返回对象而不仅仅是一个位置。索引具有名称和对象列表。这些对象可以是不同的底层类型,因此索引对象是IHasUUID,这表明项目具有 UUID。
public class DataIndex
{
public string Name;
public IDictionary<string, List<IHasUUID>> Index;
}
public class Indexer
{
private List<DataIndex> Indexes;
...
public List<IHasUUID> GetIndexedItems(List<IHasUUID> indexBy)
{
var indexer = GetIndexByKeys<IHasUUID>(indexBy);
var indexHash = GetHashKey(indexBy);
return GetIndexValues<IHasUUID>(indexer, indexHash);
}
private List<T> GetIndexValues<T>(DataIndex indexBy, string indexHash) where T : IHasUUID
{
if (indexBy == null)
return new List<T>();
return ((IList<T>)indexBy.Index[indexHash]).ToList();
}
}
我使用反射方法生成字典的键,我查看用作索引键的事物并附加类型字符串名称
所以我让我的引擎去 FindRecords,没问题
public List<T> FindRecords<T>(IHasUUID indexBy) where T : IHasUUID
{
var indexedIds = Indexer.GetIndexedItems(new List<IHasUUID>() { indexBy });
return ((IList<T>)indexedIds).ToList();
}
在这里,我在 FindRecords 返回时遇到了一堵墙
我有
return ((IList<T>)indexedIds).ToList();
我试过了
return indexedIds.ToList();
没有一个人能够施展到 T。这可能吗?
提前致谢
编辑
我确实看起来更近了,
public class DataIndex
{
public DataIndex()
{
Index = new Dictionary<string, IEnumerable<IHasUUID>>();
}
public string Name;
public Dictionary<string, IEnumerable<IHasUUID>> Index;
}
public class Indexer
{
private List<DataIndex> Indexes;
public Indexer()
{
Indexes = new List<DataIndex>();
}
public IEnumerable<T> GetIndexedItems<T>(IEnumerable<IHasUUID> indexBy) where T : IHasUUID
{
var indexer = GetIndexByKeys<T>(indexBy);
var indexHash = GetHashKey(indexBy);
return GetIndexValues<T>(indexer, indexHash);
}
private IEnumerable<T> GetIndexValues<T>(DataIndex dataIndex, string indexHash) where T : IHasUUID
{
if (dataIndex == null)
return new List<T>();
return dataIndex.Index[indexHash].ToList() as List<T>;
}
}
但是,我从GetIndexValues 得到了空回。我也尝试将它作为 IEnumerable 返回,也为 null
这是我的添加到索引方法
public void AddManyToIndex<T>(IEnumerable<IHasUUID> keys, IEnumerable<IHasUUID> newItems) where T : IHasUUID
{
var index = GetIndexByKeys<T>(keys) ?? CreateIndex<T>(keys);
string indexKey = GetHashKey(keys);
if (!index.Index.ContainsKey(indexKey))
{
index.Index[indexKey] = new List<IHasUUID>();
}
var list = index.Index[indexKey].ToList();
list.AddRange(newItems.ToList());
index.Index[indexKey] = list as IEnumerable<IHasUUID>;
}
【问题讨论】:
-
" 一个索引有一个名称和一个对象列表" - 考虑使用与“索引”不同的术语来描述这一点,因为 C# 中的“索引”专门指使用
[]运算符。 -
GetIndexedItems返回List<IHasUUID>,而不是List<T>,并且List<T>类型(不是接口IList<T>)不支持泛型类型协方差。 -
return indexedIds.Cast<T>().ToList();怎么样?不过,它需要在每个元素上运行Cast<>()。但是,您如何期望 C# 知道特定的IHasUUID是T?仅仅因为猫是宠物,并不意味着宠物就是猫。 -
@Dai 是正确的。顺便说一句,您真的需要从这些方法中获取和返回列表吗? IMO,这是糟糕的 API 设计。你可以使用
IReadOnlyList<T>或IEnumerable<T> -
@JordanBrooklyn 数组实现
IReadOnlyList<T>。
标签: c# generics reflection interface