集合的排序和利用LINQ的查找

本文详细介绍了.NET Framework中的List集合的排序方法,包括对于不同类型的元素使用sort()函数的操作,以及如何通过继承IComparable接口或实现IComparer接口来自定义排序逻辑。此外,还展示了如何使用LINQ语法进行集合的高效查询,通过where方法筛选特定条件的数据,并通过扩展方法增强代码的可读性和简洁性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

.net Framework提供了大量集合(collection)类,我们这里以最常用List为例,总结他的排序和查询。

List<T>是一个泛型集合,相比ArrayList,不用进行每次操作的装箱拆箱工作。

一、集合的排序

如果T为值类型可以直接使用sort():

      List<int> Numbers=new List<int> (){4,5,1,8,3,2,7};
      Numbers.Sort();

如果T为一个引用类型,如自己设定的类,将有以下两种方法:

1.将此类继承IComparable接口: 

     public enum KindOfDuck
    {
        Mallard, Muscovy, Decoy
    }

     public class Duck:IComparable<Duck>
     {
         public int Size;
         public KindOfDuck Kind;

         public int CompareTo(Duck other)
         {
             //从小到大排列,当前鸭子与更小的鸭子比较时,返回一个负数
             return this.Size.CompareTo(other.Size);
         }
     }

    class Program
    {     
        static void Main(string[] args)
        {
                List<Duck> Ducks = new List<Duck>()
            {
                new Duck(){Kind=KindOfDuck.Mallard,Size=17},
                new Duck(){Kind=KindOfDuck.Mallard,Size=18},
                new Duck(){Kind=KindOfDuck.Mallard,Size=14},
                new Duck(){Kind=KindOfDuck.Mallard,Size=11},
                new Duck(){Kind=KindOfDuck.Mallard,Size=14},
                new Duck(){Kind=KindOfDuck.Mallard,Size=13},
            };

                Ducks.Sort();
                Console.Read();
        }
    }

2.写一个单独的类帮助List排序,实现IComparer接口:

     public  class Duck
    {
        public int Size;
        public KindOfDuck Kind;                
    }

    public class DuckCompare_bySize : IComparer<Duck>
    {
        public int Compare(Duck x, Duck y)
        {
            return x.Size.CompareTo(y.Size);
        }
    }

    public enum KindOfDuck
    {
        Mallard, Muscovy, Decoy
    }

    class Program
    {     
        static void Main(string[] args)
        {
                List<Duck> Ducks = new List<Duck>()
            {
                new Duck(){Kind=KindOfDuck.Mallard,Size=17},
                new Duck(){Kind=KindOfDuck.Mallard,Size=18},
                new Duck(){Kind=KindOfDuck.Mallard,Size=14},
                new Duck(){Kind=KindOfDuck.Mallard,Size=11},
                new Duck(){Kind=KindOfDuck.Mallard,Size=14},
                new Duck(){Kind=KindOfDuck.Mallard,Size=13},
            };
             DuckCompare_bySize dc = new DuckCompare_bySize();       
             Ducks.Sort(dc);                               
        }
    }

二、集合的查找

利用LINQ语法查询,会使集合的查询非常简单,看下面这个简单的例子:

     class Program
    {
        static void Main(string[] args)
        {
            List<Book> books = new List<Book>()
            {
             new Book(){Number=1,Name="cq"},
             new Book(){Number=2,Name="cq"},
             new Book(){Number=3,Name="c"}
            };
            //要得到
            //List<Book> result = books.FindAll(book => book.Name == "cq");
            foreach (Book book in books.Where(book => book.Name == "cq"))
            {
                Console.WriteLine(book.Number);
            }
            Console.Read();
        }
    }

    public class Book
    {
        public int Number { get; set; }
        public string Name { get; set; }
    }

这里的where方法就是LINQ的方法,下面是where的定义

public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate);

this关键字是扩展方法,原本的LIST在没引用lINQ时是没有这个where方法的,这个扩展方法在静态类中声明,定义一个静态方法,其中第一个参数定义是它的扩展类型。

这里举个简单的例子,现在List没有Foreach方法,我们扩展一下:

     class Program
    {
        static void Main(string[] args)
        {
            List<Book> books = new List<Book>()
            {
             new Book(){Number=1,Name="cq"},
             new Book(){Number=2,Name="cq"},
             new Book(){Number=3,Name="c"}
            };

            books.Where(book => book.Name == "cq").ForEach
                (
                book => { Console.WriteLine(book.Number); }
                );
            Console.Read();
        }
    }

    public class Book
    {
        public int Number { get; set; }
        public string Name { get; set; }
    }

    public static class IEnumerableExtension
    {
        public static void ForEach<T>(this IEnumerable<T> enumeration, Action<T> action)
        {
            foreach (var item in enumeration)
            {
                action(item);
            }
        }
    }
这样同样能得到上述结果。后面这个链接里还有一些拓展方法: IEnumerable的扩展方法

这里再说明一下Func<TSource, bool> predicate这个委托,它的定义为:

public delegate TResult Func<in T, out TResult>(T arg)

如果没有这个委托,传统的实现方法:

using System;

delegate string ConvertMethod(string inString);

public class DelegateExample
{
   public static void Main()
   {
      // Instantiate delegate to reference UppercaseString method
      ConvertMethod convertMeth = UppercaseString;
      string name = "Dakota";
      // Use delegate instance to call UppercaseString method
      Console.WriteLine(convertMeth(name));
   }

   private static string UppercaseString(string inputString)
   {
      return inputString.ToUpper();
   }
}

使用这个委托会使代码变得更简洁:

using System;

public class LambdaExpression
{
   public static void Main()
   {
      Func<string, string> convert = s => s.ToUpper();
      string name = "Dakota";
      Console.WriteLine(convert(name));   
   }
}

后面链接文章有一些利用LINQ的算法:.net3.5下使用LINQ递归算法实现简洁代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值