zoukankan      html  css  js  c++  java
  • 解决C#中dynamic类型作为泛型参数的反射问题

    C#中dynamic类型作为泛型参数传递过去后,反射出来的对象类型是object,我用老外的这篇博文中的代码跑起来,得出的结果是:Flying using a Object map (a map),将Fly<T>(T map)方法的代码改为如下代码,即可获取dynamic对象的原始类型:

    Type t = typeof(T);
    if (t == typeof(object))
    {
        t = map.GetType();
    }
    Console.WriteLine("Flying using a {0} map ({1})", t.Name, map);

    实际项目中用到了MvcContrib,在调用OrderBy时传入的是IQueryable<dynmaic>对象,反射此类对象的属性时,会报异常,MvcContrib.Sorting中代码是这样的:

    public static IQueryable<T> OrderBy<T>(this IQueryable<T> datasource, string propertyName, SortDirection direction)
            {
                if(string.IsNullOrEmpty(propertyName))
                {
                    return datasource;
                }
    
                var type = typeof(T);
    
                var property = type.GetProperty(propertyName);   //这里报异常
    
                if(property == null)
                {
                    throw new InvalidOperationException(string.Format("Could not find a property called '{0}' on type {1}", propertyName, type));
                }
    
                var parameter = Expression.Parameter(type, "p");
                var propertyAccess = Expression.MakeMemberAccess(parameter, property);
                var orderByExp = Expression.Lambda(propertyAccess, parameter);
    
                const string orderBy = "OrderBy";
                const string orderByDesc = "OrderByDescending";
    
                string methodToInvoke = direction == SortDirection.Ascending ? orderBy : orderByDesc;
    
                var orderByCall = Expression.Call(typeof(Queryable), 
                    methodToInvoke, 
                    new[] { type, property.PropertyType }, 
                    datasource.Expression, 
                    Expression.Quote(orderByExp));
    
                return datasource.Provider.CreateQuery<T>(orderByCall);
            }

    原因是调用此方法时,如果传入的泛型是dynamic,typeof(T)得出的结果是object,接下来的property将会出异常。

    解决的办法是:在 var type = typeof(T); 后面加一段判断语句,代码如下:

    var type = typeof(T);
    if(type == typeof(object))
    {
        type = datasource.FirstOrDefault().GetType();
    }

    这样就可以获取IQueryable<dynmaic>的原始类型。

  • 相关阅读:
    2020系统综合实践 第1次实践作业
    软工实践个人总结
    2019 SDN大作业
    HDU 4965 Fast Matrix Calculation (矩阵快速幂取模----矩阵相乘满足结合律)
    HDU 1565 (最大流+黑白染色化二分图求最小割)
    HDU 4289 Control (最大流+拆点)
    HDU 3605 Escape(最大流+缩点转换)
    HDOJ4886(hash+枚举)
    POJ 2446 Chessboard (二分匹配)
    POJ 1469 COURSES (二分匹配,邻接表)
  • 原文地址:https://www.cnblogs.com/ShineTan/p/6380994.html
Copyright © 2011-2022 走看看