微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – Boxed Value类型比较

我想要实现的是盒装原始类型的直接比较.
((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类型作为对象,它将使用对象重载.

原文地址:https://www.jb51.cc/csharp/95508.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐