尝试扩展List<T>类中的LastIndexOf方法

今天在学习Linq的基础知识的时候遇到这么一个问题:

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5
  6 namespace DemoLinq
  7 {
  8     class Program
  9     {
 10         public static LinqData dataForTest = new LinqData { Name = "lsb", Score = "85", Age = 15 };
 11         static void Main(string[] args)
 12         {
 13             List<LinqData> linqDatas = new List<LinqData>();
 14             linqDatas.Add(new LinqData() { Name = "zsgg", Score = "98", Age = 12 }); //这里使用了对象初始化器
 15             linqDatas.Add(new LinqData() { Name = "lsb", Score = "85", Age = 15 });
 16             linqDatas.Add(new LinqData() { Name = "ww", Score = "87", Age = 15 });
 17             linqDatas.Add(new LinqData() { Name = "zd", Score = "85", Age = 18 });
 18             int lastIndex=linqDatas.LastIndexOf(dataForTest);
 19             Console.WriteLine(lastIndex);
 20         }
 21
 22     }
 23
 24     public class LinqData
 25     {
 26         public string Name { get; set; }
 27         public string Score { get; set; }
 28         public int Age { get; set; }
 29
 30     }
 31
 32
 33 }
 34 

original code

在18行用List<T>类内置的LastIndexOf方法来求取对象的下标时发现其下标一直为-1(即未在linqDatas集合中找到dataForTest对象),可是该集合中明明包含dataForTest对象的,这是为什么呢?

经过群里好友的提醒我明白了,原来是LastIndexOf方法内置的比较逻辑无法判别出两个LinqData对象是相等的,故而无法找到dataForTest对象,所以返回-1。那么该怎么办呢?我的想法是对LastIndexOf方法进行扩展。故而有了以下的代码:

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5
  6 namespace DemoLinq
  7 {
  8     class Program
  9     {
 10         public static LinqData dataForTest = new LinqData { Name = "lsb", Score = "85", Age = 15 };
 11         static void Main(string[] args)
 12         {
 13
 14             List<LinqData> linqDatas = new List<LinqData>();
 15             linqDatas.Add(new LinqData() { Name = "zsgg", Score = "98", Age = 12 }); //这里使用了对象初始化器
 16             linqDatas.Add(new LinqData() { Name = "lsb", Score = "85", Age = 15 });
 17             linqDatas.Add(new LinqData() { Name = "ww", Score = "87", Age = 15 });
 18             linqDatas.Add(new LinqData() { Name = "zd", Score = "85", Age = 18 });
 19 	       int lastIndex=linqDatas.LastIndexOf(dataForTest);
 20             Console.WriteLine(lastIndex);
 21         }
 22
 23
 24     }
 25
 26     public class LinqData:IEquatable<LinqData>  //自定义类需实现IEquatable<T>接口
 27     {
 28         public string Name { get; set; }
 29         public string Score { get; set; }
 30         public int Age { get; set; }
 31
 32         public bool Equals(LinqData other)
 33         {
 34            return Name.Equals(other.Name) && Score.Equals(other.Score) && Age.Equals(other.Age);
 35         }
 36     }
 37
 38
 39
 40     public static class Extend
 41     {
 42
 43         public static int MyLastIndexOf<TSource>(this IEnumerable<TSource> source, TSource item)  where TSource:IEquatable<TSource>
 44         {
 45             List<TSource> data = source.ToList();
 46             int index = -1;
 47             foreach (TSource t in data)
 48             {
 49                 if (t.Equals(item))
 50                 {
 51                     index = data.Count - 1 - data.IndexOf(t);
 52                 }
 53             }
 54             return index;
 55         }
 56
 57
 58     }
 59 }
 60 

new code

主要思路如下:

  • 自定义类实现IEquatable<T>接口(即实现Equals方法来定义判等规则)
  • 编写扩展方法MyLastIndexOf(注意扩展方法的参数,在这里为this IEnumerable<TSource> source与TSource item)
  • 对扩展方法添加泛型约束(where TSource:IEquatable<TSource>)
时间: 2024-09-28 06:32:26

尝试扩展List<T>类中的LastIndexOf方法的相关文章

StringBuilder类中的重要方法

下面的API注解包含了StringBuilder类中的重要方法 append(boolean b):将 boolean 参数的字符串表示形式追加到序列. append(char c):将 char 参数的字符串表示形式追加到此序列. append(char[] str):将 char 数组参数的字符串表示形式追加到此序列. append(char[] str,int offset,int len):将 char 数组参数的子数组的字符串表示形式追加到此序列. append(CharSequenc

PHP通过反射方法调用执行类中的私有方法

PHP 5 具有完整的反射 API,添加了对类.接口.函数.方法和扩展进行反向工程的能力. 下面我们演示一下如何通过反射,来调用执行一个类中的私有方法: <?php //MyClass这个类中包含了一个名为myFun的私有方法class MyClass {        private $tmp = 'hello';        private function myFun()    {        echo $this->tmp . ' ' . 'world!';    }} //通过类

面向对象:类中的特殊方法

一.前言 类的特殊方法,其实就是遇到类代码特定的语法  然后去执行指定的特殊方法.只是一个对应的映射关系比如: 这么多特殊方法,其实是为了不同的特定语法设计,大家都遵守这个约定. python内部根据特殊的语法帮我们映射到特殊的方法,里面的逻辑由我们自己实现 当然你可以打破这个规定,比如__int__是转换成数字类型,你可以写成相加,但是强烈不推荐这样使用,不然你的代码只有你自己看得懂.别人看起来就费劲. 二.各种特殊方法 2.1 类与对象调用自动执行 __init__ 类()  自动执行该方法

Java线程状态及Thread类中的主要方法

要想实现多线程,就必须在主线程中创建新的线程对象. 任何线程一般具有5种状态,即创建,就绪,运行,阻塞,终止. 创建状态: 在程序中用构造方法创建了一个线程对象后,新的线程对象便处于新建状态,此时,他已经有了相应的内存空间和其他资源,但还处于不可运行状态. 就绪状态: 新建线程对象后,调用该线程的start()方法可以启动线程.当线程启动时,线程进入就绪状态.此时,线程将进入线程队列排队,等待CPU服务,这表明它已经具备了运行条件.-------(运行start()方法只是进入就绪状态,并没有开

14 在公有类中使用访问方法而非公有域

class Point{ public double x; public double y; } 对于可变的类来说,应该用包含私有域和公有设值方法的类来代替: class Point{ private double x; private double y; Point(double x, double y) { this.x = x; this.y = y; } double getX() { return x; } void setX(double x) { this.x = x; } dou

问题1、java.lang中String类和Object类中的equals方法比较

String类中的equals方法重写了Object类中的equals方法,下面通过代码来比较二者的不同之处: 一.String类 1. String s1 = "String"; String s2 = "String"; System.out.println(s1 == s2 ); System.out.println(s1.equals(s2));

Object 类中的 equals方法

1 相等与同一 如果两个对象具有相同的类型以及相同的属性值,则称这两个对象相等.如果两个引用对象指的是同一个对像,则称这两个变量同一.Object类中定义的equals 函数原型为:public boolean equals(Object);他是判断两个对象是否同一,并不是是否相等. 2 equals方法 由于Object 类是所有类的最高基类,所有其他类都继承类Object类的equals()方法,定义原型如下: public boolean equals (Object x){ return

java.long.object类中的重要方法

一:概念 java.long.object Object类是所有Java类的祖先.每个类都使用 Object 作为超类. 二:方法概览 clone() 创建并返回此对象的一个副本. equals(Object obj) 指示某个其他对象是否与此对象“相等”. finalize() 当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法.(JVM中自带的垃圾回收机制只能回收new出的对象) getClass() 返回一个对象的运行时类. hashCode() 返回该对象的哈希码值

java 静态导入、System类、Date类、Runtime类、Calendar类、Collections类中的shuffle方法、Math类

/* JDK1.5版本新特性(续):静态导入 注意:当类名重名时,需要指定具体的包名: 当方法名重名时,需要指定具体的类名. */ import java.util.*; import static java.util.Arrays.*;//导入Arrays工具类中的所有静态成员. import static java.lang.System.*;//导入了System类中所有的静态成员,注意System类中的成员都是静态的. class StaticImport { public static