【问题标题】:Problem comparing items implementing IComparable比较实现 IComparable 的项目时出现问题
【发布时间】:2016-10-03 20:40:06
【问题描述】:

我正在研究一种扩展方法,它通过特定选择器找到最小项目。代码下方

    public static T MinBy<T, K>(this IEnumerable<T> src, Func<T, K> selector) where K : struct, IComparable, IConvertible
    {
        var min = default(K);
        T minItem = default(T);
        foreach (var item in src)
        {
            var current = selector(item);
            if (current < min)
            {
                min = current;
                minItem = item;
            }
        }

        return minItem;

    }

它给出错误Error Operator '&lt;' cannot be applied to operands of type 'K' and 'K'。但我已指定通用约束 K 应为Struct and IComparable。我相信所有的数值数据类型都可以满足于此。

那怎么会是无效操作呢?

【问题讨论】:

    标签: c# generics icomparable


    【解决方案1】:

    IComparable 没有(也不能)谈论运营商。您应该使用:

    if (current.CompareTo(min) < 0)
    

    运算符是静态的,并且只会重载而不是覆盖。您不能在接口中要求运算符,并且方法的存在不会神奇地改变运算符将做什么。 (例如,覆盖 Equals 不会改变 == 的行为方式。)

    您还应该注意,由于您的约束仅涉及非泛型 IComparable 接口,因此您将在每个操作中装箱。我建议您将约束更改为IComparable&lt;K&gt;。 (或者按照 Marc 的建议,放弃约束并使用 Comparer&lt;K&gt;.Default。)

    关于您的方法的其他一些 cmets:

    • 如果所有键值都大于 K 的默认值(例如 K=int 并且所有键都是正数),那么您将找不到项目
    • 您可能希望有一个接受特定 IComparare&lt;K&gt; 的重载(但前提是您放弃了可比较的约束)
    • 实际上没有必要将K 限制为值类型。如果我想找到字典上名字最早的人怎么办?
    • 如果没有元素,则返回T的默认值;为了适应 LINQ 的其余部分,我建议抛出 InvalidOperationException
    • 我建议使用TSourceTKey 作为类型参数以更符合LINQ

    您可能想查看MoreLINQ MinBy implementation 作为替代方案。 (再看一遍,我不确定要求 comparer 为非空对我们来说是个好主意;如果比较器为空,它可能应该像普通 LINQ 一样使用默认比较器。)

    【讨论】:

    • “例如,覆盖 Equals 确实会改变 == 的行为方式” - 这可能应该说“没有改变”?
    【解决方案2】:

    IComparable 不提供 operator 支持 - 您需要使用 current.CompareTo(min)。或者更好的是,使用Comparer&lt;T&gt;.Default.Compare(current,min) - 然后您可以删除约束并且它将自动处理空值等,并且它将避免装箱。

    var comparer = Comparer<T>.Default;
    ...
    // loop
        if(comparer.Compare(current, min) < 0) {...}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-29
      • 2021-04-09
      • 1970-01-01
      • 2023-03-19
      • 1970-01-01
      相关资源
      最近更新 更多