• 17.比较


    1.类型比较

    使用GetType()和typeof()比较类型

                AddClass1 c1 = new AddClass1();
    
                if (c1.GetType() == typeof(AddClass1))
                { 
                    //dosomething
                }

    1.1.封箱和拆箱

    封箱是指把值类型转换为System.Object类型,或者转换为由值类型实现的接口。

                struct MyStruct
               {
                     public int Val;
               }
    
                MyStruct valType1 = new MyStruct();
                valType1.Val = 5;
                object refType = valType1;//把结构类型放在object类型的变量中以封箱它                    

    注:以这种方式封装而创建的对象包含的是值类型的一个副本的引用,而不是包含源值类型的引用

                valType1.Val = 6;
                MyStruct valType3 = (MyStruct)refType;//拆箱
                Console.WriteLine(valType3.Val);//5

    如果是把引用类型的对象赋值给Object 类型的变量则新变量包含的是源对象的引用,这取决于值类型和引用类型的存储的区别,因为值类型存储的是一个值,引用类型存储的是对象的地址。

    值类型封装成它实现的接口

        interface MyInterface
        { }
    
        struct MyStruct:MyInterface
        {
            public int Val;
        }
    
                MyStruct valType1 = new MyStruct();
                valType1.Val = 5;
                MyInterface refType2 = valType1;

    1.2.is运算符

    is运算符可以检查对象是否是给定类型,或者可以转换为给定类型。

    is运算符的语法如下:

    <operand> is <type>

    1) 如果type 是一个类类型,operand 也是该类型,或者operand 继承于该类型,或者它可以封箱到该类型,那么表达式的结果为true;

    2)如果type是一个接口类型,operand也是该类型,或者operand实现了该接口,则表达式的结果为true;

    2)如果type是一个值类型,operand也是该类型,或者operand可以拆箱为该类型,那么表达式的结果为true。

     int i=0;
     Console.WriteLine(i is object);//true

    2.值比较

    2.1运算符重载

    比较两个人的年龄可以像如下这样比较

    if(pseron1.Age>person2.Age)
    {
       //dosomething       
    }

    但是如果要直接比较两个对象,就必须要在该对象的类中对运算符进行重载,以定义比较的规则。

        class AddClass1
        {
            public int Val;
            public static bool operator ==(AddClass1 c1, AddClass1 c2)
            {
                return c1.Val == c2.Val;
            }
    
            public static bool operator !=(AddClass1 c1, AddClass1 c2)
            {
                return !(c1 == c2);
            }
    
            public override bool Equals(object obj)
            {
                //return this.Val==((AddClass1)obj).Val;
                return this == (AddClass1)obj;
            }
    
            public override int GetHashCode()
            {
                return Val;
            }
        }
                AddClass1 c1 = new AddClass1();
                c1.Val = 5;
    
                AddClass1 c2 = new AddClass1();
                c2.Val = 5;
    
                Console.WriteLine(c1 == c2);//true
                Console.WriteLine(c1.Equals(c2));//true

    重载运算符必须成对进行,比如重载了==,就必须重载!=,重载了>,就必须重载<。可以在别的运算符中使用已重载的运算符。一般重载了==和!==运算符要一起重写Equals和GetHashCode方法,因为这两个方法也是用来做比较的,这样做能让用户不管怎么操作结果都一致。

    注:不能重载赋值运算符=和复合赋值运算符,如+=,也不能重载&&和||,可以重载&和|。

    2.2IComparable和IComparer接口

    IComparable和 IComparer接口是.net提供的比较两个对象的标准方法,这两个方法是区别是:

    1)IComparable接口要在需要比较的对象的类中实现,可以比较该对象和另一个对象;

    2)IComparer接口在一个单独的类中实现,可以比较两个对象。

    IComparable用来提供对象的默认比较方法,如果要提供其他比较方法一般新建一个类继承IComparer。对象集合排序时必须要提供默认比较方法实现,即继承IComparable接口,因为Sort()方法会调用默认的比较方法。也可以给Sort()方法传递一个实现IComparer接口的对象,以便用别的方法排序。

    IComparable接口提供了一个CompareTo方法,该方法返回一个int 类型的数据,可以确定两个对象的差距有多大。IComparer 接口提供了Compare()方法,返回int类型的数据,其含义和CompareTo一样。

    以下是比较两个对象的例子

    public class Person:IComparable
        {
            public string Name { get; set; }
            public int Age { get; set; }
    
            [System.Xml.Serialization.XmlElementAttribute("Books")]
            public Books Books { get; set; }
    
    
            public Person(string name, int age)
            {
                Name = name;
                Age = age;
            }
    
            public int CompareTo(object obj)
            {
                return this.Age-((Person)obj).Age;
            }
        }
    
        public class PersonComparerName:IComparer
        {
            public static IComparer Default = new PersonComparerName();
    
            public int Compare(object x, object y)
            {
                if (x is Person && y is Person)
                {
                    return Comparer.Default.Compare(((Person)x).Name, ((Person)y).Name);
                }
                else
                    throw new ArgumentException("One or both object to compare is not Person objects.");
            }
        }
    
    
            static void Main(string[] args)
            {
    
                ArrayList list = new ArrayList();
                list.Add(new Person("Jim",30));
                list.Add(new Person("Bob", 25));
                list.Add(new Person("Bert", 27));
    
                Console.WriteLine(((Person)list[0]).CompareTo((Person)list[1]));//Jim比Bob大5岁,所以返回5
                Console.WriteLine(PersonComparerName.Default.Compare((Person)list[0],(Person)list[1]));//Jim 首字母J比Bob首字母排在后面,所以返回1
    
    
                Console.WriteLine("原始数据");
                foreach (object o in list)
                { 
                    Person p =(Person)o;
                    Console.WriteLine("Name:{0},Age:{1}", p.Name, p.Age);
                }
    
                Console.WriteLine("默认排序");
    
                list.Sort();//调用Person默认排序方法
                foreach (object o in list)
                {
                    Person p = (Person)o;
                    Console.WriteLine("Name:{0},Age:{1}", p.Name, p.Age);
                }
    
                Console.WriteLine("按照名字排序");
                list.Sort(PersonComparerName.Default);
                foreach (object o in list)
                {
                    Person p = (Person)o;
                    Console.WriteLine("Name:{0},Age:{1}", p.Name, p.Age);
                }
    
                Console.ReadLine();
            }
        }

    .net 提供了一个比较简单类型的类Comparer,我们可以直接使用它来比较简单类型的数据。一般比较的结果为-1 、0 、1.

            static void Main(string[] args)
            {
    
                string firstString = "First string";
                string secondString = "Second string";
                string thirdString = "First string";
    
                //因为F在字母表中排在S前面,所以第一个比较结果是-1
                Console.WriteLine("Comparing {0} and {1} ,result:{2}", firstString, secondString, Comparer.Default.Compare(firstString, secondString));
                //第一个和第三个字符串一样,结果返回0
                Console.WriteLine("Comparing {0} and {1} ,result:{2}", firstString, thirdString, Comparer.Default.Compare(firstString, thirdString));
    
                int firtNum = 12;
                int secondNum = 24;
    
                //12比24小,返回-1
                Console.WriteLine("Comparing {0} and {1} ,result:{2}", firtNum, secondNum, Comparer.Default.Compare(firtNum, secondNum));
                Console.ReadLine();
            }
  • 相关阅读:
    hmset
    java 调用mongo 判断大于等于 并且小约等于<=
    Maven项目,别人的没问题,自己机器一直有问题
    linux 时间datetimectl 问题
    真正手把手教 git
    0324-SQLMAP使用参数备注
    安全推荐网址:
    JavaScript Base64 作为文件上传的实例代码解析
    学习笔记|变量的解构赋值
    学习笔记|let 和 const 命令
  • 原文地址:https://www.cnblogs.com/lidaying5/p/10595526.html
Copyright © 2020-2023  润新知