Core源码(六)Array.Sort

Sort方法

源码在位置在corefx\src\System.Runtime.Extensions\src\System\Collections\ArrayList.cs

corefx是.net 的源码库,直接在github搜索即可

// Sorts the elements in this list.  Uses Array.Sort with the
// provided comparer.
public virtual void Sort(IComparer comparer)
{
    Sort(0, Count, comparer);
}

这里会根据IComparer类型进行排序,如果不传入会使用默认值

 

IComparer

[NullableContextAttribute(2)]
public interface IComparer
{
    //
    // 摘要:
    //     Compares two objects and returns a value indicating whether one is less than,
    //     equal to, or greater than the other.
    //
    // 参数:
    //   x:
    //     The first object to compare.
    //
    //   y:
    //     The second object to compare.
    //
    // 返回结果:
    //     A signed integer that indicates the relative values of x and y: - If less than
    //     0, x is less than y. - If 0, x equals y. - If greater than 0, x is greater than
    //     y. .
    //
    // 异常:
    //   T:System.ArgumentException:
    //     Neither x nor y implements the System.IComparable interface. -or- x and y are
    //     of different types and neither one can handle comparisons with the other.
    int Compare(object? x, object? y);
}

 

 

Comparer默认实现

[Serializable]
[System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
public sealed class Comparer : IComparer, ISerializable
{
    private CompareInfo _compareInfo;

    public static readonly Comparer Default = new Comparer(CultureInfo.CurrentCulture);
    public static readonly Comparer DefaultInvariant = new Comparer(CultureInfo.InvariantCulture);

    // Compares two Objects by calling CompareTo.
    // If a == b, 0 is returned.
    // If a implements IComparable, a.CompareTo(b) is returned.
    // If a doesn't implement IComparable and b does, -(b.CompareTo(a)) is returned.
    // Otherwise an exception is thrown.
    // 
    public int Compare(Object a, Object b)
    {
        if (a == b) return 0;
        if (a == null) return -1;
        if (b == null) return 1;

        string sa = a as string;
        string sb = b as string;
//都不为空的情况,直接调用Compare
        if (sa != null && sb != null)
            return _compareInfo.Compare(sa, sb);

        IComparable ia = a as IComparable;
        if (ia != null)
            return ia.CompareTo(b);

        IComparable ib = b as IComparable;
        if (ib != null)
            return -ib.CompareTo(a);

        throw new ArgumentException(SR.Argument_ImplementIComparable);
    }
}

 

CompareInfo

对比的核心方法

[Serializable]
[System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
public partial class CompareInfo : IDeserializationCallback

public virtual int Compare(string string1, string string2)
{
    return (Compare(string1, string2, CompareOptions.None));
}

public virtual int Compare(string string1, string string2, CompareOptions options)
{
    //Our paradigm is that null sorts less than any other string and
    //that two nulls sort as equal.
    if (string1 == null)
    {
        if (string2 == null)
        {
            return (0);     // Equal
        }
        return (-1);    // null < non-null
    }
    if (string2 == null)
    {
        return (1);     // non-null > null
    }

    if (_invariantMode)
    {
        if ((options & CompareOptions.IgnoreCase) != 0)
            return CompareOrdinalIgnoreCase(string1, string2);

        return String.CompareOrdinal(string1, string2);
    }

    return CompareString(string1.AsSpan(), string2.AsSpan(), options);
}

 

CompareOrdinal方法是实际进行字符串对比的,位于framework程序集中。

#region 程序集 mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

// C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\mscorlib.dll

#endregion

这里我下载了4.5的源码,位于如下位置

C:\project\SourceCode\1 net framework\Source\NDP\clr\src\BCL\System

// Compares strA and strB using an ordinal (code-point) comparison.
//
[Pure]
public static int CompareOrdinal(String strA, String strB) 
{
    // Most common case, first character is different.
    if ((strA.m_firstChar - strB.m_firstChar) != 0)
    {
        return strA.m_firstChar - strB.m_firstChar;
    }
    //首字母相同的情况下,金星整个字符串的对比
    return CompareOrdinalHelper(strA, strB);
}

 

自己定义IComparer

class Program
{
    static void Main()
    {
        Employee [] employees = new Employee[4];
        for (int i = 0; i < 4; i++)
        {
            employees[i] = new Employee();
        }
        employees[0].Age = 12;
        employees[1].Age = 34;
        employees[2].Age = 64;
        employees[3].Age = 53;
        Array.Sort(employees, new EmployeeSortAdapter());
        foreach (Employee emp in employees)
        {
            Console.WriteLine(emp.Age);
        }
        Console.Read();
    }
}
public class Employee
{
    public int Age { get; set; }
}
class EmployeeSortAdapter :IComparer<Employee>
{
    public int Compare(Employee emp1, Employee emp2)
    {
        if (emp1==null&&emp2==null)
        {
            return 0;
        }

        if (emp1==null)
        {
            return -1;
        }

        if (emp2==null)
        {
            return 1;
        }
      

        if (emp1.Age > emp2.Age)
        {
            return 1;
        }

        else if (emp1.Age < emp2.Age)
        {
            return -1;
        }
        return 0;
    }
}
自定义排序

 

posted @ 2020-04-01 16:38  SeedQi  阅读(246)  评论(0编辑  收藏  举报