使用泛型实现get all查询时泛型T无ID定义编译报错如何解决
问题原因
编译器不知道你传入的泛型类型T包含ID属性,所以需要通过泛型约束明确告诉编译器T的结构特征。
解决方案
方案1:泛型接口约束(最推荐,类型安全无性能损耗)
- 先定义公共实体接口,统一ID属性规范:
// 接口内ID的类型请和你所有Model的ID实际类型保持一致,比如是Guid就改为Guid public interface IEntity { int ID { get; set; } }
- 所有数据库映射的Model类都实现该接口:
// 示例:你的用户Model实现IEntity接口 public class UserModel : IEntity { public int ID { get; set; } // 其他Model原有属性保持不变 }
- 给泛型方法添加接口约束,修正后的代码如下:
public static class DB_TableToHashTable { // where T : IEntity 表示传入的T必须实现IEntity接口,一定包含ID属性 public static Hashtable dbTableToHashTable<T>(string tableName) where T : IEntity { List<T> myList = GlobalConfig.Connection.GenericGetAll<T>(tableName); Hashtable table = new Hashtable(); foreach (var item in myList) { table.Add(item.ID, item); } return table; } }
该方案支持编译时类型校验,不符合要求的类型传入时会直接在编译阶段报错,避免运行时异常。
方案2:动态类型绕开编译检查(仅临时兜底使用)
如果你暂时不想修改所有Model的定义,可以用dynamic绕开编译校验,但是该方案丢失了编译时检查,只有运行时才能判断T是否包含ID属性,性能也更差,不建议长期使用。
修改后的代码如下:
public static class DB_TableToHashTable { public static Hashtable dbTableToHashTable<T>(string tableName) { List<T> myList = GlobalConfig.Connection.GenericGetAll<T>(tableName); Hashtable table = new Hashtable(); foreach (var item in myList) { // 转成dynamic跳过编译检查 table.Add(((dynamic)item).ID, item); } return table; } }
额外优化建议
现在已经不推荐使用非泛型的Hashtable了,你可以直接用泛型字典Dictionary<int, T>替代,不需要装箱拆箱,类型更安全,代码也更简洁:
public static Dictionary<int, T> DbTableToDictionary<T>(string tableName) where T : IEntity { List<T> myList = GlobalConfig.Connection.GenericGetAll<T>(tableName); return myList.ToDictionary(x => x.ID); }
内容的提问来源于stack exchange,提问作者Harbie
相关产品推荐
相关产品推荐

