场景:方法定义了一个泛型T,需要根据泛型的具体类型做特殊处理:当类型为Page< T >(一个泛型类)时,要拿到Page里面的T的具体类型,然后对应到另一个泛型类List< T >,最后调用另一个泛型方法JsonConvertUtil.DeserializeObject< T >(string jsonStr, JsonSerializerSettings settings)这里的T指定为List< T >
分析:一开始的思路是想着通过一些方法能得到T的具体类型Page< A >,然后直接调用DeserializeObject< List< A > >,尝试了一下,发现语法不通。当我们不确定泛型的具体类型时,或只能在运行时获取具体类型,正确的做法应该是使用反射。就好比我们得到了一个类型Type objType,却不能使用 objType obj= new objType()一样
方法:
public void T Test<T>(this string jsonStr) where T : class{
//对泛型类型的判断,要先判断IsGenericType,再比较GetGenericTypeDefinition
if (typeof(T).IsGenericType && typeof(T).GetGenericTypeDefinition() == typeof(Page<>){
//声明类型List<>,并设置List<T1>里面的T1为T(Page<T2>)里的T2
//typeof(T).GetGenericArguments()[0]即获取T(Page<T2>)里的T2
var listType = typeof(List<>).MakeGenericType(typeof(T).GetGenericArguments()[0]);
//通过反射获取泛型方法,并把上一步得到的listType做为方法的泛型类型,MakeGenericMethod(listType)
var desMethod = typeof(JsonConvertUtil).GetMethod("DeserializeObject",
new Type[] { typeof(string), typeof(JsonSerializerSettings) }).MakeGenericMethod(listType);
//执行方法
var fragmentList = desMethod.Invoke(null, new object[] { bigStr.GetFragmentStr(i), GlobalDesSettings });
}
}