joh*_*ass 12 c# reflection boxing unboxing value-type
我在这里想要实现的是盒装基元类型的直接值比较.
((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)
Run Code Online (Sandbox Code Playgroud)
我理解'为什么'.我只是没有看到'怎么样'.
这些类型在运行时之前是未知的,它们可以是来自数据源的任何基本类型.这包括字符串,日期时间,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);
<... 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 ...>
Run Code Online (Sandbox Code Playgroud)
最终的方法结果是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);
}
Run Code Online (Sandbox Code Playgroud)
**更新**两种类型的通用args都可以推断,并在arg2上增加了更多的编译时间安全性,以确保它在编译时是IConvertible.
给定这个泛型函数,以下所有内容现在都返回true(不需要指定类型参数,因为从第一个参数推断出来:
Console.WriteLine(ValueEquality(1, "1"));
Console.WriteLine(ValueEquality(2, 2.0));
Console.WriteLine(ValueEquality(3, 3L));
Run Code Online (Sandbox Code Playgroud)
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);
}
Run Code Online (Sandbox Code Playgroud)
这将适用于对象:
object obj1 = 1;
object obj2 = 1.0;
Console.WriteLine(ValueEquality(obj1, obj2));
Run Code Online (Sandbox Code Playgroud)
正如我所说的,这两个都可以作为重载共存,所以如果直接比较兼容的IConvertible类型它将使用泛型,如果你只有盒装类型作为对象,它将使用对象重载.
| 归档时间: |
|
| 查看次数: |
3548 次 |
| 最近记录: |