比较两个通用值的最佳方法?

时间:2017-10-22 09:40:25

标签: c# generics operator-overloading comparator icomparable

我正在写一个小班,我需要像dll那样四处走动,它会有不同的排序算法。我希望这些函数可以处理任何类型的列表,包括对象。所以它基本上是这样的:

class TemplateSortings<T>
{
    List<T> GNRList;

    static void SortBubble<T>()
    {
        //Do stuff with GNRList, which can be a list of any values (nums, strings, objects)
    }
}

现在我遇到麻烦的问题是 - 比较两个通用值的最佳方法是:重载比较运算符还是让类继承IComparable接口?什么更好,为什么?

2 个答案:

答案 0 :(得分:3)

如果您希望它适用于任何类型,您可能不应将T限制为实现IComparable的类型,因为并非所有类型都适用。

解决此问题的一种简单方法是让调用者决定如何比较对象。你只需要一个额外的参数:

static void SortBubble(Func<T, T, int> comparator)
{
    ...
}

您可以使用2个参数调用comparator,它将为您提供负值0​​或正值,表示第一个参数小于,等于或大于第二个参数。

例如,您可以使用SortBubble这样调用int

var sorting = new TemplateSortings<int>();
// populate the list...
sorting.SortBubble((x, y) => x.CompareTo(y)) // pass a lambda

编辑:

如果您不想要额外的参数并且想要检查方法内部的类型,您可以这样做:

if (typeof(IComparable<T>).IsAssignableFrom(typeof(T))) {
    // do your sorting
    // you need to cast values of type "T" to "Comparable<T>" like this
    // var castedValue = (IComparable<T>)tValue;
} else {
    throw ...
}

答案 1 :(得分:0)

您可以对代码进行概括,以便它可以使用任何可能有效的类型T

public static IEnumerable<T> BubbleSort(
    this IEnumerable<T> source,
    IComparer<T> comparer == null)
{
    var currentComparer = comparer ?? Comparer<T>.Default;
    //bubble sort with currentComparator 
}

现在,您可以对任何T进行排序,如果:

  1. T实施IComparable<T>
  2. T实现了遗留IComparable
  3. 您提交了一个知道如何比较Comparator s
  4. T

    当您尝试执行第一次比较时,它将在任何其他情况下失败。