盒装价值类型比较

我在这里想要实现的是盒装基元类型的直接值比较。

((object)12).Equals((object)12); // Type match will result in a value comparison, ((object)12).Equals((object)12d); // but a type mismatch will not. (false) object.Equals((object)12,(object)12d); // Same here. (false) 

我理解’为什么’。 我只是没有看到’怎么样’。

这些类型在运行时之前是未知的,它们可以是来自数据源的任何基本类型。 这包括字符串,日期时间,bool等等。我已经走下了编写扩展方法的丑陋路线,该方法解决了两种类型,然后在进行’=​​=’比较之前进行转换:(为了完整性,我包括了每种基本类型,加上我感兴趣的那些)

 public static bool ValueEquals(this object thisObj, object compare) { if (thisObj is int) { int obj = (int)thisObj; if (compare is int) return (obj == (int)compare); if (compare is uint) return (obj == (uint)compare); if (compare is decimal) return (obj == (decimal)compare); if (compare is float) return (obj == (float)compare);  } if (thisObj is uint) { uint obj = (uint)thisObj; if (compare is int) return (obj == (int)compare); if (compare is uint) return (obj == (uint)compare);  } if (thisObj is decimal) { decimal obj = (decimal)thisObj; if (compare is int) return (obj == (int)compare);  

最终的方法结果是300多行,这很好(但很可怕),但现在我需要做的不仅仅是’==’。 我需要>,<, =,!=。

reflection中有什么东西我可以用于盒装值类型比较吗?

什么都没有?

看起来你假设arg1中的类型是你要转换的类型,所以我会使用这样的genric。 只要arg2是IConvertible(int,double,所有数字,字符串等都是IConvertible),这将起作用:

 public static bool ValueEquality(T1 val1, T2 val2) where T1 : IConvertible where T2 : IConvertible { // convert val2 to type of val1. T1 boxed2 = (T1) Convert.ChangeType(val2, typeof (T1)); // compare now that same type. return val1.Equals(boxed2); } 

** UPDATE **两种类型的通用args都可以推断出来,并在arg2上增加了更多的编译时间安全性,以确保它在编译时是IConvertible。

给定此generics函数,以下所有内容现在都返回true(不需要指定类型参数,因为从第一个参数推断出来:

  Console.WriteLine(ValueEquality(1, "1")); Console.WriteLine(ValueEquality(2, 2.0)); Console.WriteLine(ValueEquality(3, 3L)); 

UPDATE

根据你的评论,如果你拥有的只是对象,这里就是一个重载。 两者都可以共存,它会根据参数调用一个更合适的:

  public static bool ValueEquality(object val1, object val2) { if (!(val1 is IConvertible)) throw new ArgumentException("val1 must be IConvertible type"); if (!(val2 is IConvertible)) throw new ArgumentException("val2 must be IConvertible type"); // convert val2 to type of val1. var converted2 = Convert.ChangeType(val2, val1.GetType()); // compare now that same type. return val1.Equals(converted2); } 

这将适用于对象:

  object obj1 = 1; object obj2 = 1.0; Console.WriteLine(ValueEquality(obj1, obj2)); 

正如我所说的,这两个都可以作为重载共存,所以如果直接比较兼容的IConvertible类型,它将使用generics,如果你只有盒装类型作为对象,它将使用对象重载。

如果使用IComparable而不是手册,请查看 – http://msdn.microsoft.com/en-us/library/system.icomparable.compareto.aspx

如果将来需要类似的东西,首先考虑对一个操作数的类型进行切换,并为每个类型实现“操作处理程序”类,并使用方法处理操作,如IntOpHandler.PerformOp(int left, object right)

您还可以通过首先合并多个类型(即byte,short,ushort,int,uint,long – cast to long first,然后执行long操作)来减少需要处理的类型数量。