/// <summary>
        /// 并行排序,并返回排序后的List列表
        /// 自定义列与升倒序键值对
        /// </summary>
        /// <param name="list"></param>
        /// <param name="sort">Key:名称,值:true:升序,false:倒序</param>
        public static void Sort <T>(this List <T> list, Dictionary <string, bool> sort)
        {
            if (sort == null || sort.Count == 0)
            {
                throw new ArgumentException("Sorting is not set.");
            }
            if (list.Count == 0)
            {
                return;
            }
            var item     = sort.ElementAt(0);
            var type     = list[0].GetType();
            var builder  = SortBuilder.CreateBuilder(type, item.Key, out bool iString);
            var property = type.Property(item.Key);
            OrderedParallelQuery <T> orderBy;

            if (iString)
            {
                orderBy = item.Value ? list.AsParallel().OrderBy(c => builder.Build(c) as string, new StringComparer()) :
                          list.AsParallel().OrderByDescending(c => builder.Build(c) as string, new StringComparer());
            }
            else
            {
                orderBy = item.Value ? list.AsParallel().OrderBy(c => builder.Build(c)) : list.AsParallel().OrderByDescending(c => builder.Build(c));
            }
            for (int i = 1; i < sort.Count; i++)
            {
                item = sort.ElementAt(i);
                var builder2 = SortBuilder.CreateBuilder(type, item.Key, out iString);
                property = type.Property(item.Key);
                if (iString)
                {
                    orderBy = item.Value ? orderBy.ThenBy(c => builder2.Build(c) as string, new StringComparer()) :
                              orderBy.ThenByDescending(c => builder2.Build(c) as string, new StringComparer());
                }
                else
                {
                    orderBy = item.Value ? orderBy.ThenBy(c => builder2.Build(c)) : orderBy.ThenByDescending(c => builder2.Build(c));
                }
            }
            var temp = orderBy.ToList();

            list.Clear();
            list.AddRange(temp);
        }
Example #2
0
        /// <summary>
        /// 生成动态代码,创建委托
        /// </summary>
        public static SortBuilder CreateBuilder(Type type, string name, out bool iString)
        {
            iString = false;
            var property = type.Property(name);

            if (property == null)
            {
                throw new ArgumentException(name + " Argument can not be empty.");
            }
            if (!property.CanRead)
            {
                throw new ArgumentException("Cannot read value.");
            }

            var getTCompareInt = typeof(BuilderHelper).GetMethod(nameof(BuilderHelper.TCompareInt),
                                                                 TConfig.Flags, null, new Type[] { typeof(object) }, null);
            var getTCompareLong = typeof(BuilderHelper).GetMethod(nameof(BuilderHelper.TCompareLong),
                                                                  TConfig.Flags, null, new Type[] { typeof(object) }, null);
            var getTCompareDouble = typeof(BuilderHelper).GetMethod(nameof(BuilderHelper.TCompareDouble),
                                                                    TConfig.Flags, null, new Type[] { typeof(object) }, null);

            var dbType = property.PropertyType;

            if (dbType.IsGenericType && Nullable.GetUnderlyingType(dbType) != null)
            {
                dbType = Nullable.GetUnderlyingType(dbType);
            }
            if (dbType.IsEnum)
            {
                dbType = dbType.GetEnumUnderlyingType();
            }
            var dymMethod = new DynamicMethod(type.Name + nameof(SortBuilder), typeof(string), new Type[] { typeof(object) }, true);

            switch (dbType.Name)
            {
            case nameof(Int32):
            case nameof(Int16):
            case nameof(Byte):
            case nameof(Boolean):
            case nameof(Image):
            case nameof(Bitmap):
                dymMethod = new DynamicMethod(type.Name + nameof(SortBuilder), typeof(int), new Type[] { typeof(object) }, true);
                break;

            case nameof(Int64):
            case nameof(DateTime):
                dymMethod = new DynamicMethod(type.Name + nameof(SortBuilder), typeof(long), new Type[] { typeof(object) }, true);
                break;

            case nameof(Double):
            case nameof(Single):
            case nameof(Decimal):
                dymMethod = new DynamicMethod(type.Name + nameof(SortBuilder), typeof(double), new Type[] { typeof(object) }, true);
                break;
            }
            var generator = dymMethod.GetILGenerator(); // Create ILGenerator

            generator.GetValue(property, type);         //获取引用值
            switch (dbType.Name)
            {
            case nameof(Int32):
            case nameof(Int16):
            case nameof(Byte):
            case nameof(Boolean):
            case nameof(Image):
            case nameof(Bitmap):
                generator.Emit(OpCodes.Call, getTCompareInt);    //调用静态方法
                break;

            case nameof(Int64):
            case nameof(DateTime):
                generator.Emit(OpCodes.Call, getTCompareLong);    //调用静态方法
                break;

            case nameof(Double):
            case nameof(Single):
            case nameof(Decimal):
                generator.Emit(OpCodes.Call, getTCompareDouble);    //调用静态方法
                break;

            default:
                //String不用再次转化
                //generator.Emit(OpCodes.Call, getTCompareString);//调用静态方法
                break;
            }
            generator.Emit(OpCodes.Ret);

            var builder = new SortBuilder();

            switch (dbType.Name)
            {
            case nameof(Int32):
            case nameof(Int16):
            case nameof(Byte):
            case nameof(Boolean):
            case nameof(Image):
            case nameof(Bitmap):
                builder.handler = dymMethod.CreateDelegate(typeof(Func <object, int>));
                break;

            case nameof(Int64):
            case nameof(DateTime):
                builder.handler = dymMethod.CreateDelegate(typeof(Func <object, long>));
                break;

            case nameof(Double):
            case nameof(Single):
            case nameof(Decimal):
                builder.handler = dymMethod.CreateDelegate(typeof(Func <object, double>));
                break;

            default:
                iString         = true;
                builder.handler = dymMethod.CreateDelegate(typeof(Func <object, string>));
                break;
            }
            return(builder);
        }