ASP.NET Core 6中ISession扩展方法如何针对IEnumerable返回新实例
解决ASP.NET Core 6中ISession扩展方法返回null的问题
错误原因
你之前的代码报错Using the generic type 'IEnumerable' requires 1 type arguments,是因为IEnumerable如果不指定命名空间,默认会匹配泛型接口System.Collections.Generic.IEnumerable<T>,它必须传入类型参数。若要引用非泛型的可枚举接口,需要明确写全称System.Collections.IEnumerable。
方案一:重载扩展方法(推荐)
通过重载区分可枚举类型和普通类型,代码更清晰且性能更好:
// 基础版本:适用于所有类型,保持原有逻辑 public static T? Get<T>(this ISession session, string key) { var value = session.GetString(key); return value == null ? default : JsonSerializer.Deserialize<T>(value); } // 重载版本:专门处理实现非泛型IEnumerable且有默认构造函数的引用类型 public static T Get<T>(this ISession session, string key) where T : class, System.Collections.IEnumerable, new() { var value = session.GetString(key); // 反序列化失败时也返回空实例,避免后续空引用问题 return value == null ? new T() : JsonSerializer.Deserialize<T>(value) ?? new T(); }
调用Context.Session.Get<List<SavedQueries>>("SavedQueries")时,会自动匹配第二个重载,直接返回空List<SavedQueries>而非null,无需额外的null判断。
方案二:单方法内通过反射自动判断
如果不想编写重载,可以用反射在同一个方法里判断目标类型是否符合条件:
public static T? Get<T>(this ISession session, string key) { var value = session.GetString(key); var targetType = typeof(T); // 判断是否为可枚举类型且有无参构造函数 bool canCreateEmptyInstance = typeof(System.Collections.IEnumerable).IsAssignableFrom(targetType) && targetType.GetConstructor(Type.EmptyTypes) != null; if (value == null) { return canCreateEmptyInstance ? (T?)Activator.CreateInstance(targetType) : default; } var result = JsonSerializer.Deserialize<T>(value); // 反序列化结果为null时,若满足条件则返回空实例 return result ?? (canCreateEmptyInstance ? (T?)Activator.CreateInstance(targetType) : default); }
这个方法会自动识别List<SavedQueries>这类可枚举类型,在value为null或反序列化失败时返回空实例,其他类型则保持原有逻辑。
内容的提问来源于stack exchange,提问作者Yasser Sobhdel
相关产品推荐
相关产品推荐

