我想要实现的是盒装原始类型的直接比较.
((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)
我明白’为什么’.我只是看不到“怎么样”.
类型在运行时是未知的,它们可以是数据源中的任何原始类型.包括字符串,数据时间,布尔等
我已经下了一个编写扩展方法的丑恶的路线,这个方法可以同时运行两种类型,然后在进行“==”比较之前进行投射:(为了完整,我包括每个原始类型,加上我感兴趣的)
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); <... and so on for each primitive type ...> } if (thisObj is uint) { uint obj = (uint)thisObj; if (compare is int) return (obj == (int)compare); if (compare is uint) return (obj == (uint)compare); <... Again for each primitive type ...> } if (thisObj is decimal) { decimal obj = (decimal)thisObj; if (compare is int) return (obj == (int)compare); <... Etc,etc ...>
得到的方法证明是300行长,这是罚款(但可怕的),但现在我需要做的不仅仅是’==’.我需要>,< =,> =,!=.
反思中有什么可以用于盒装价值类型比较吗?
有什么事吗
解决方法
看起来你假设arg1的类型是你要转换的类型,所以我会使用这样的genric.只要arg2是IConvertible(int,double,所有的数字,字符串等都是IConvertible),这将工作:
public static bool ValueEquality<T1,T2>(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 **使两种类型的通用参数,都可以推断,并在arg2上添加更多的编译时安全性,以确保在编译时它的IConvertible.
给定这个通用函数,所有以下内容现在返回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类型,它将使用泛型,如果你只是将Boxed类型作为对象,它将使用对象重载.