【问题标题】:Comparing Two values in a generic method c#在泛型方法c#中比较两个值
【发布时间】:2014-10-16 10:40:06
【问题描述】:

我认为我的代码对于我想要实现的目标是不言自明的:

private bool Comparison<T>(T operatorOne, T operatorTwo, string operand)
    {
        switch (operand.ToLower())
        {
            case "=":
                return operatorOne.Equals(operatorTwo);
            case "<":
                return operatorOne < operatorTwo;
            case ">":
                return operatorOne > operatorTwo;
            case "contains":
                return operatorOne.ToString().Contains(operatorTwo.ToString());
            default:
                return false;
        }
    }

它给了我错误:

Error   16  Operator '>','<' cannot be applied to operands of type 'T' and 'T'

我需要一个可以比较字符串、Int、Double、chars 的方法。 注意:排除字符串将被传递为>或

【问题讨论】:

  • 您将“运算符”和“操作数”的概念倒过来。在表达式a + b 中,ab 是操作数,+ 是运算符。
  • 是的,对不起!我的错:)
  • 你对T有什么了解,如果你规定where T : IComparable,你可能就可以逍遥法外了。
  • @mrtig T 在我的情况下只能是 int、double、float、decimal、string、char

标签: c# generics comparison operators operands


【解决方案1】:

您可以使用Comparer&lt;T&gt;.Default.Compare(operatorOne, operatorTwo) 进行比较。请注意,如果T 没有实现IComparableIComparable&lt;T&gt;Comparer&lt;T&gt;.Default.Compare 会抛出异常。

为确保T 实现IComparable,您可以添加where T: IComparable 约束。 (它将排除实现IComparable&lt;T&gt; 的类,但不 IComparable。仍然可以接受,因为许多实现IComparable&lt;T&gt; 的类也实现了IComparable。)

private bool Comparison<T>(T operatorOne, T operatorTwo, string operand)
    where T: IComparable
{
    switch(operand.ToLower())
    {
        case "=":
            return Comparer<T>.Default.Compare(operatorOne, operatorTwo) == 0;
        case "<":
            return Comparer<T>.Default.Compare(operatorOne, operatorTwo) < 0;
        case ">":
            return Comparer<T>.Default.Compare(operatorOne, operatorTwo) > 0;
        case "contains":
            return operatorOne.ToString().Contains(operatorTwo.ToString());
        default:
            return false;
    }
}

附言

按照 Servy 的建议,您也可以将 IComparer 作为额外参数传递给函数。它将允许覆盖既不实现IComparable 也不实现IComparable&lt;T&gt; 的类型,因此Comparer&lt;T&gt;.Default 不适用于它们。

另外,感谢 @TimothyShields,他推荐了Comparer&lt;T&gt;.Default

【讨论】:

  • @isumit With Comparer。默认你甚至可以删除where 约束。
  • @AlexD 你可以但你不应该,除非你接受IComparer作为参数。如果类型没有实现IComparable&lt;T&gt;,给定的代码将在运行时失败;使用泛型约束,如果使用了不合适的类型,代码将在编译时失败。
  • @Servy 我只是在编辑答案。这里的一个小问题是Comparer&lt;T&gt;.Default.Compare 可能返回IComparable&lt;T&gt;IComparable,这很难通过where 约束来表达。我们可以说where IComparable,因为实现IComparable&lt;T&gt; 的类通常也实现IComparable。但它仍然打开了一个仅实现IComparable&lt;T&gt; 的极端情况。
  • @AlexD 这就是为什么我总是接受比较器作为参数,而不是期望实现默认的比较器。您会看到 BCL 做同样的事情。这允许使用不实现任一接口的类型。
  • @Servy 您的意思是将比较器作为Comparison&lt;T&gt; 函数的额外参数吗?当然,这样的比较器可以比较任何东西,但它会改变函数签名。
猜你喜欢
  • 2014-11-18
  • 1970-01-01
  • 1970-01-01
  • 2015-06-01
  • 1970-01-01
  • 2022-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多