【问题标题】:Best way to compare two generic values?比较两个通用值的最佳方法?
【发布时间】:2018-04-03 00:17:38
【问题描述】:

我正在编写一个小类,我会在需要时像 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 接口?什么更好,为什么?

【问题讨论】:

    标签: c# generics operator-overloading comparator icomparable


    【解决方案1】:

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

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

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

    您可以使用 2 个参数调用 comparator,它会给您一个负值、0 或一个正值,表示第一个参数小于、等于或大于第二个参数。

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

    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 ...
    }
    

    【讨论】:

    • 这有点无效,你不觉得吗?我现在可能知道我将使用哪些变量,所以我正在考虑将列表传递给 GNRList,然后对其进行排序。我不知道它会是什么类型...
    • 这毫无意义。您必须告诉它如何对项目进行排序,否则计算机怎么知道? @Alucard
    • 我希望函数本身检查列表的类型。如果我必须使用小数或字符串怎么办?我是否必须编写另一个 SortBubble 函数,但这次使用 ?或者我可以只检查函数内部的类型吗? @Sweeper
    • 如果传入的东西无法比较怎么办? @Alucard
    • 像什么?我很可能会知道它是否无与伦比。我总是可以抛出异常或编写自己的函数进行比较。如果是对象...我没有考虑太多,但我可能会按其中一个变量对它们进行排序,例如 ID 或另一个函数中的其他值,或者我会传递一个由这些组成的列表上述变量?可能是。 @Sweeper
    【解决方案2】:

    您可以概括您的代码,以便它可以与任何可能有效的类型 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&lt;T&gt;
    2. T 实现旧版 IComparable
    3. 您传递了一个知道如何比较Ts 的Comparator

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多