如何访问Hashtable中DataItem泛型类的ItemType属性?
解决Hashtable中泛型DataItem的ItemType属性访问问题
这个问题我之前也碰到过,核心原因是Hashtable存储的是object类型对象,编译器没办法知道_data[itemName]具体是哪一个泛型版本的DataItem,自然就识别不了ItemType属性。下面给你几个可行的解决思路,按推荐程度排序:
方案1:用泛型Dictionary+非泛型接口(最推荐,类型安全)
Hashtable是.NET早期的非泛型集合,现在更推荐用泛型Dictionary来保留类型信息。我们可以先定义一个非泛型接口,让所有DataItem泛型类都实现它,这样就能统一访问ItemType属性:
步骤1:定义非泛型接口
public interface IDataItem { // 用object类型统一暴露ItemType object ItemType { get; } }
步骤2:修改DataItem类实现接口
public class DataItem<T,T1,T2> : IDataItem { public T ItemName { get; set; } public T1 ItemContent { get; set; } public T2 ItemType { get; set; } // 显式实现接口,避免和泛型属性冲突 object IDataItem.ItemType => ItemType; public DataItem(T name, T1 content, T2 type) { ItemName = name; ItemContent = content; ItemType = type; } }
步骤3:替换Hashtable为泛型Dictionary
把原来的Hashtable换成Dictionary<object, IDataItem>(键类型可以根据你的实际需求调整,比如如果键都是string,就用Dictionary<string, IDataItem>):
private readonly Dictionary<object, IDataItem> _data = new Dictionary<object, IDataItem>();
步骤4:修改GetType方法
现在就能安全地转换为IDataItem并访问ItemType了:
public Tuple<ResultStatus, T1> GetType<T,T1>(T itemName) { if (!_data.ContainsKey(itemName)) { return new Tuple<ResultStatus, T1>(ResultStatus.Success, (T1)(object)0); } else { var dataItem = (IDataItem)_data[itemName]; return new Tuple<ResultStatus, T1>(ResultStatus.Success, (T1)dataItem.ItemType); } }
方案2:直接指定泛型类型转换(不推荐,类型不安全)
如果你不想改集合类型,也可以尝试在GetType方法里指定完整的泛型参数,把取出的object转换为对应的DataItem<T,T1,T2>。但这种方法要求调用GetType时必须明确T2的类型,否则会抛出转换异常,风险很高:
// 注意这里新增了T2泛型参数 public Tuple<ResultStatus, T1> GetType<T,T1,T2>(T itemName) { if (!_data.ContainsKey(itemName)) { return new Tuple<ResultStatus, T1>(ResultStatus.Success, (T1)(object)0); } else { var dataItem = (DataItem<T,T1,T2>)_data[itemName]; return new Tuple<ResultStatus, T1>(ResultStatus.Success, (T1)(object)dataItem.ItemType); } }
方案3:反射访问属性(最不推荐,性能差)
如果实在没办法调整结构,也可以用反射来获取ItemType的值,但反射性能低,代码可读性差,只适合临时救急:
public Tuple<ResultStatus, T1> GetType<T,T1>(T itemName) { if (!_data.ContainsKey(itemName)) { return new Tuple<ResultStatus, T1>(ResultStatus.Success, (T1)(object)0); } else { var dataItem = _data[itemName]; var itemTypeProp = dataItem.GetType().GetProperty("ItemType"); var itemTypeValue = itemTypeProp?.GetValue(dataItem); return new Tuple<ResultStatus, T1>(ResultStatus.Success, (T1)itemTypeValue); } }
内容的提问来源于stack exchange,提问作者Rudi Encok
相关产品推荐
相关产品推荐

