自己造轮子之给Array类型添加方法

一、前言

学C#已经两个月了,决定记录和检验一下自己的学习成果。.NET本身不支持Array类型的实例排序,只能用静态方法和Linq实现排序,用扩展方法和泛型给它扩展一下。目标:让代码可以这样写

        static void Main(string[] args)
        {
            char[] array= {'a','e','c','b'};
            array.QuickSort();
            foreach(char ji in array)
            {
                Console.WriteLine(ji);
            }
                
            array.Reverse();
            foreach (char ji in array)
            {
                Console.WriteLine(ji);
            }
        }

提示:以下是本篇文章正文内容

二、思路

因为不确定Array是什么类型,所以肯定需要使用T类型。先弄一个比较器Comparer,它继承IComparer接口,在快排算法里依赖注入。

三、实现

1. 构建比较器

每个类型都弄个对应的比较器,这样在快排算法里才会自动找到对应的比较器。最开始我用if(x>y) return 1;if(x<y) return -1;if(x==y) return 0;后来想想直接return x-y就好,最后发现每个方法只有一行,limbda表达式就可以了。

    public class IntComparer : IComparer<int>
    {
        public int Compare(int x, int y)=> x - y;
    }
    public class UIntComparer : IComparer<uint>
    {
        public int Compare(uint x, uint y)=> (int)(x - y);
    }
    public class DoubleComparer : IComparer<double>
    {
        public int Compare(double x, double y) => (int)(x - y);
    }
    public class FloatComparer : IComparer<float>
    {
        public int Compare(float x, float y) => (int)(x - y);
    }
    public class LongComparer : IComparer<long>
    {
        public int Compare(long x, long y) => (int)(x - y);
    }
    public class ULongComparer : IComparer<ulong>
    {
        public int Compare(ulong x, ulong y)=> (int)(x - y);
    }
    public class ByteComparer : IComparer<byte>
    {
        public int Compare(byte x, byte y) => x - y;
    }
    public class DecimalComparer : IComparer<decimal>
    {
        public int Compare(decimal x, decimal y) => (int)(x - y);
    }
    public class SbyteComparer : IComparer<sbyte>
    {
        public int Compare(sbyte x, sbyte y) => (x - y);
    }
    public class ShortComparer : IComparer<short>
    {
        public int Compare(short x, short y) => (x - y);
    }
    public class UShortComparer : IComparer<ushort>
    {
        public int Compare(ushort x, ushort y) => (x - y);
    }
    public class CharComparer:IComparer<char>
    {
        public int Compare(char x, char y) => (x - y);
    }
    public class myStringComparer : IComparer<string>
    {
        public int Compare(string str1, string str2) =>str1.CompareTo(str2);
    }

2. 实现快排算法

        public static void QuickSorting<T> (T[] array, IComparer<T> comparer,int low, int high)//from small to big
        {
            if(low>=high)
                return;
            T index=array[low];
            int rightSide=high, leftSide=low;
            while(leftSide<rightSide)
            {
                while(comparer.Compare(array[rightSide],index)>0&&leftSide<rightSide)
                {
                    rightSide--;
                }
                if(leftSide<rightSide)
                    array[leftSide++]=array[rightSide];
                while(comparer.Compare(array[leftSide],index)<0&&leftSide<rightSide)
                {
                    leftSide++;
                }
                if(leftSide<rightSide)
                    array[rightSide--]=array[leftSide];
            }
            array[leftSide]=index;
            QuickSorting<T>(array,comparer,low,leftSide-1);
            QuickSorting<T>(array,comparer,rightSide+1,high);
        }

3. 调用快排算法

这里费了很多时间,不知道如何获取T的类型,甚至用了反射Activator.CreateInstance(typeof(T)),先建空对象再GetType()。但是测试发现String类型的构造函数必须有参数。最后才用typeof(T).Name解决了这个问题。

        public static void QuickSort<T>(this T[] array)
        {
            switch (typeof(T).Name)
            {
                case "Int32":
                    SortingMethods.QuickSorting((int[])Convert.ChangeType(array, typeof(int[])), new IntComparer(), 0, array.Length - 1);
                    break;
                case "UInt32":
                    SortingMethods.QuickSorting((uint[])Convert.ChangeType(array, typeof(uint[])), new UIntComparer(), 0, array.Length - 1);
                    break;
                case "Double":
                    SortingMethods.QuickSorting((double[])Convert.ChangeType(array, typeof(double[])), new DoubleComparer(), 0, array.Length - 1);
                    break;
                case "Single":
                    SortingMethods.QuickSorting((float[])Convert.ChangeType(array, typeof(float[])), new FloatComparer(), 0, array.Length - 1);
                    break;
                case "Int64":
                    SortingMethods.QuickSorting((long[])Convert.ChangeType(array, typeof(long[])), new LongComparer(), 0, array.Length - 1);
                    break;
                case "ULong":
                    SortingMethods.QuickSorting((ulong[])Convert.ChangeType(array, typeof(ulong[])), new ULongComparer(), 0, array.Length - 1);
                    break;
                case "Byte":
                    SortingMethods.QuickSorting((byte[])Convert.ChangeType(array, typeof(byte[])), new ByteComparer(), 0, array.Length - 1);
                    break;
                case "Decimal":
                    SortingMethods.QuickSorting((decimal[])Convert.ChangeType(array, typeof(decimal[])), new DecimalComparer(), 0, array.Length - 1);
                    break;
                case "SByte":
                    SortingMethods.QuickSorting((sbyte[])Convert.ChangeType(array, typeof(sbyte[])), new SbyteComparer(), 0, array.Length - 1);
                    break;
                case "Int16":
                    SortingMethods.QuickSorting((short[])Convert.ChangeType(array, typeof(short[])), new ShortComparer(), 0, array.Length - 1);
                    break;
                case "UInt16":
                    SortingMethods.QuickSorting((ushort[])Convert.ChangeType(array, typeof(ushort[])), new UShortComparer(), 0, array.Length - 1);
                    break;
                case "String":
                    SortingMethods.QuickSorting((string[])Convert.ChangeType(array, typeof(string[])), new myStringComparer(), 0, array.Length - 1);
                    break;
                case "Char":
                    SortingMethods.QuickSorting((char[])Convert.ChangeType(array, typeof(char[])), new CharComparer(), 0, array.Length - 1);
                    break;
            }
        }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值