3

我有一些非常古老的 VB.Net 代码是:

 Private Function Min(ByVal A As Object, ByVal B As Object) As Object
            If A Is DBNull.Value Or B Is DBNull.Value Then Return DBNull.Value
            If A < B Then Return A Else Return B
        End Function

不用担心。编译器吃掉它......并要求更多。但是当转换为 C# 时:

    private object Min(object A, object B)
    {
        if (object.ReferenceEquals(A, DBNull.Value) | object.ReferenceEquals(B, DBNull.Value))
            return DBNull.Value;
        return A < B ? A : B;
    }

编译器阻塞它并显示错误消息:

Cannot apply operator '<' with operands of object and object

那么,到底是什么东西哟?

4

5 回答 5

6

该代码仅适用于 VB,因为您使用的是Option Strict Off. 一般来说,这是非常糟糕的做法。好吧,正如你所说,这是旧代码。在现代代码(无论是 VB 还是 C#)中,您会使用泛型或/和接口。由于以下原因,代码无法直接转换为泛型,DBNull但这是 VB 中泛型方法的样子(没有DBNull检查):

Function Min(Of T As IComparable(Of T))(a As T, b as T) As T
    Return If(a.CompareTo(b) < 0, a, b)
End Function

回到您的代码,您可以IComparable在确保它们不是之后简单地将两个参数转换为DBNull,然后执行等效操作:

private object Min(object A, object B)
{
    if (A == DBNull.Value || B == DBNull.Value)
        return DBNull.Value;
    return ((IComparable) A).CompareTo(B) < 0 ? A : B;
}

(为了完整起见,C# 4 有一个dynamic关键字,它允许在道德上等同于旧的 VB 代码,即将方法分派到运行时。但是,我认为这不是这里最直接的解决方案,我通常更喜欢使用 as尽可能多地静态检查类型信息。)

于 2013-06-06T12:51:19.407 回答
2

本页解释了 < 运算符的行为方式(包括应用于像您的案例这样的两个对象时)。

http://msdn.microsoft.com/en-us/library/cey92b0t (v=vs.80).aspx(参见“使用关系比较运算符的无类型编程”部分)。

就像 Konrad Rudolph 建议的那样,将其转换为 C# 的最佳方法是使用 IComparable 但是,我想在您的情况下,如果您正在比较数字,您可以简单地使用 Math.Min() ,因为将此运算符应用于对象(VB 编译它但抛出一个异常,如上面链接中所述)。

于 2013-06-06T12:55:50.210 回答
2

另一种方法是编写一个泛型方法,您可以在其中强制实施要实现的类型IComparable

   public object Min<T>(T A, T B)
      where T: IComparable
   {
      if (object.ReferenceEquals(A, DBNull.Value) | 
          object.ReferenceEquals(B, DBNull.Value))
         return DBNull.Value;
      return A.CompareTo(B) < 0 ? A : B;
   }
于 2013-06-06T12:58:45.237 回答
0

在vb中,如果你有明确的关闭和严格的关闭,编译器会吃很多东西。据我所知,在 c# 中不存在这样的东西。

于 2013-06-06T12:39:08.353 回答
0

是的,您不能在对象上使用比较运算符。请确保将字符串作为参数传递。

于 2013-06-06T12:41:26.350 回答