栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

创建对象时需要考虑是否实现比较器

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

创建对象时需要考虑是否实现比较器

创建对象时需要考虑是否实现比较器

1、基础

  有对象的地方,一般都会存在比较。在此根据一个Salary列表实现对象比较的例子。Salary类需要实现接口IComparable。

class Salary:IComparable
{    public string Name { get; set; }    public int baseSalary { get; set; }    public int Bonus { get; set; }    public int CompareTo(object obj)
    {
        Salary salary = obj is Salary ? obj as Salary : null;        if(salary==null)
        {            throw new Exception("类型不同,无法比较");
        }        if(baseSalary>salary.baseSalary)
        {            return 1;
        }        else if(baseSalary==salary.baseSalary)
        {            return 0;
        }        else
        {            return -1;
        }        //以上代码可有以下代码代替,使用整型默认比较方法        //return baseSalary.CompareTo(salary.baseSalary);    }
}

  实现接口IComparable后,可以根据baseSalary对Salary集合对象排序。在Main函数中代码如下:

public static void Main()
{
    ArrayList companySalary = new ArrayList();
    companySalary.Add(new Salary() { Name = "Mike", baseSalary = 3000,Bonus=1000 });
    companySalary.Add(new Salary() { Name = "Rose", baseSalary = 2000, Bonus = 6000 });
    companySalary.Add(new Salary() { Name = "Tom", baseSalary = 5000, Bonus = 5000 });
    companySalary.Add(new Salary() { Name = "Jeffry", baseSalary = 1000, Bonus = 2000 });
    companySalary.Add(new Salary() { Name = "Steve", baseSalary = 4500, Bonus = 1900 });
    companySalary.Sort();    foreach (Salary salary in companySalary)
    {
        Console.WriteLine("{0}t baseSalary: {1}tBonus: {2}", salary.Name, salary.baseSalary,salary.Bonus);
    }}

  但是,此处实现相当于比较局限,局限与只能使用baseSalary排序,不能使用其他方式排序。如果使用Bonus进行排序,就需要改变源码。接口IComparer的作用可以避免这类问题。

2、IComparer接口

  使用IComparer接口实现一个自定义比较器:

class BonusComparer : IComparer
{     int IComparer.Compare(object x, object y)
    {
        Salary salary1 = x is Salary ? x as Salary : null;
        Salary salary2 = y is Salary ? y as Salary : null;        return salary1.Bonus.CompareTo(salary2.Bonus);
    }
}

  在主控端调用时排序时,需要在Sort方法中传入一个实现了IComparer接口的比较器对象:companySalary.Sort(new BonusComparer())。以此实现可以根据需要,实现多种比较。

3、泛型实现

  在前面,使用了性能不高的ArrayList类。在泛型出来之后,需要尽量使用泛型集合。在CompareTo和Compare和函数中,需要对对象进行转型,比较影响性能,尤其是对大型集合进行排序时,性能影响非常明显。而泛型的出现,可以避免运行时的转型。因此,上面的代码全部更换为泛型类型:

class Program
{    public static void Main()
    {
        List companySalary = new List();
        companySalary.Add(new Salary() { Name = "Mike", baseSalary = 3000, Bonus = 1000 });
        companySalary.Add(new Salary() { Name = "Rose", baseSalary = 2000, Bonus = 6000 });
        companySalary.Add(new Salary() { Name = "Tom", baseSalary = 5000, Bonus = 5000 });
        companySalary.Add(new Salary() { Name = "Jeffry", baseSalary = 1000, Bonus = 2000 });
        companySalary.Add(new Salary() { Name = "Steve", baseSalary = 4500, Bonus = 1900 });
        companySalary.Sort();        foreach (Salary salary in companySalary)
        {
            Console.WriteLine("{0}t baseSalary: {1}tBonus: {2}", salary.Name, salary.baseSalary, salary.Bonus);
        }
        companySalary.Sort(new BonusComparer());//提供一个默认比较器
        foreach (Salary salary in companySalary)
        {
            Console.WriteLine("{0}t baseSalary: {1}tBonus: {2}", salary.Name, salary.baseSalary, salary.Bonus);
        }
    }
}class Salary : IComparable{    public string Name { get; set; }    public int baseSalary { get; set; }    public int Bonus { get; set; }    public int CompareTo(Salary other)
    {        if (other == null)
        {            throw new Exception("类型不同,无法比较");
        }        if (baseSalary > other.baseSalary)
        {            return 1;
        }        else if (baseSalary == other.baseSalary)
        {            return 0;
        }        else
        {            return -1;
        }        //以上代码可有以下代码代替,使用整型默认比较方法        //return baseSalary.CompareTo(other.baseSalary);    }
}class BonusComparer : IComparer{    public int Compare(Salary x, Salary y)
    {        return x.Bonus.CompareTo(y.Bonus);
    }
}

 4、Linq实现

  针对前面实现排序方法时,需要实现多个接口,新增了方法使得代码入侵性太高。可扩展性差,对于有新的排序要求,就必须实现新的比较器。使用Linq,可以实现遍历、筛选、投影集合等功能。

class Program
{    public static void Main()
    {
        List companySalary = new List();
        companySalary.Add(new Salary() { Name = "Mike", baseSalary = 3000, Bonus = 1000 });
        companySalary.Add(new Salary() { Name = "Rose", baseSalary = 2000, Bonus = 6000 });
        companySalary.Add(new Salary() { Name = "Tom", baseSalary = 5000, Bonus = 5000 });
        companySalary.Add(new Salary() { Name = "Jeffry", baseSalary = 1000, Bonus = 2000 });
        companySalary.Add(new Salary() { Name = "Steve", baseSalary = 4500, Bonus = 1900 });        var baseSalarySort = from salary in companySalary orderby salary.baseSalary select salary;        foreach (Salary salary in baseSalarySort)
        {
            Console.WriteLine("{0}t baseSalary: {1}tBonus: {2}", salary.Name, salary.baseSalary, salary.Bonus);
        }        var bonusSort = from salary in companySalary orderby salary.Bonus select salary;        foreach (Salary salary in bonusSort)
        {
            Console.WriteLine("{0}t baseSalary: {1}tBonus: {2}", salary.Name, salary.baseSalary, salary.Bonus);
        }
    }
}class Salary
{    public string Name { get; set; }    public int baseSalary { get; set; }    public int Bonus { get; set; }
}

  Linq可以带来很大的便利性,但需要掌握比较器、迭代器、索引器的原理,以便更好地理解Linq的思想。


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/231721.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号