结构比较

数组和元组都实现接口IStructuralEquatable和IStructuralComparable.这两个接口不仅可以比较引用,还可以比较内容.这些接口都是显示实现的,所以在使用时需要把数组和元组强制转换为这个接口.IStructuralEquatable接口用于比较两个元组或数组是否有相同的内容,IStructuralComparable接口用于给元组或数组排序.

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

namespace 结构比较

{

class Program

{

static void Main(string[] args)

{

//创建两个Person项的数组.

//比较运算符!=返回true

//因为这其实是两个变量p1和p2引用的两个不同数组.

//因为array类没有重写带一个参数的Equals()放大,所以用"=="运算符

//比较引用会得到相同的结构,即这两个变量不相同

Person zhangsan = new Person { FirstName = "zhang", LastName = "san" };

Person[] p1 = {

new Person

{

FirstName="lisi"

} ,

zhangsan

};

Person[] p2 = {

new Person

{

FirstName="lisi"

} ,

zhangsan

};

if (p1!=p2)

{

Console.WriteLine("not the same reference"); ;

}

Console.ReadKey();

}

}

public class Person : IEquatable<Person>

{

public int ID { get; set; }

public string FirstName { set; get; }

public string LastName { set; get; }

public override string ToString()

{

return string.Format("{0},{1}{2}", ID, FirstName, LastName); ;

}

public override bool Equals(object obj)

{

if (obj == null)

{

throw new ArgumentNullException("obj");

}

return Equals(obj as Person);

}

public override int GetHashCode()

{

return ID.GetHashCode();

}

public bool Equals(Person other)

{

if (other == null)

{

throw new ArgumentNullException("other");

}

return this.ID == other.ID && this.FirstName == other.FirstName && this.LastName == other.LastName;

}

}

}

使用实现IEquatable接口的Person类.IEquatable接口定义了一个强类型化的Equals()方法,用来比较FirstName和LastName属性的值.

下面看看如何对元组执行相同的操作.这里创建了两个内容相同的元组实例:

var t1 = Tuple.Create<string, int>("zhangsan", 19);

var t2 = Tuple.Create<string, int>("zhangsan", 19);

//因为t1和t2引用了两个不同的对象,所以比较运算符"!="返回true

if (t1 != t2)

{

Console.WriteLine("not the same reference to the tuple");

}

//这会调用object.equals()方法比较元组的每一项,每一项都返回true

if (t1.Equals(t2))

{

Console.WriteLine("the same reference to the tuple");

}

Tuple<>类提供了两个Equals()方法:一个重写了object基类中的Equals()方法,并把object作为参数,第二个由IStructyralEqualityComparer接口定义,并把object和IequalityComparer作为参数.

还可以使用类TupleCOmparer创建一个自定义的UequalityComparer,这个类实现了IEqualityComparer接口的两个方法Equals()和GetHashCode():

public class TupleComparer : IEqualityComparer

{

public bool Equals(object x, object y)

{

return x.Equals(y);

}

public int GetHashCode(object obj)

{

return obj.GetHashCode();

}

}

实现IEqualityCOmparer接口的Equals()方法需要new修饰符或者隐式实现的接口,因为基类object也定义了带两个参数的静态的Equals()方法.

使用TupleComparer,给Tuple<T1,T2>类的Equals()方法传递一个新实例.Tuple类的Equals(0方法为要比较的每一项调用TupleComparer的Equals()方法.所以,对于Tuple<T1,T2>类,要调用两次TupleCOmparer,以检查所有项是否相等.

C#编程(三十七)----------结构比较的更多相关文章

  1. 程序员编程艺术第三十六~三十七章、搜索智能提示suggestion,附近点搜索

    第三十六~三十七章.搜索智能提示suggestion,附近地点搜索 作者:July.致谢:caopengcs.胡果果.时间:二零一三年九月七日. 题记 写博的近三年,整理了太多太多的笔试面试题,如微软 ...

  2. centos shell编程3【告警系统】 没有服务器端和客户端的概念 main.sh mon.conf load.sh 502.sh mail.php mail.sh disk.sh 第三十七节课

    centos shell编程3[告警系统]  没有服务器端和客户端的概念 main.sh mon.conf load.sh 502.sh mail.php mail.sh  disk.sh  第三十七 ...

  3. 孤荷凌寒自学python第三十七天python的文件与内存变量之间的序列化与反序列化

    孤荷凌寒自学python第三十七天python的文件与内存变量之间的序列化与反序列化 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 一.什么是序列化与反序列化 序列化是指将内存中的数据进行指 ...

  4. NeHe OpenGL教程 第三十七课:卡通映射

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  5. Linux网络编程(三)

    Linux网络编程(三) wait()还是waitpid() Linux网络编程(二)存在客户端断开连接后,服务器端存在大量僵尸进程.这是由于服务器子进程终止后,发送SIGCHLD信号给父进程,而父进 ...

  6. Golang面向对象编程-struct(结构体)

    Golang面向对象编程-struct(结构体) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.什么是面向对象编程 面向对象编程(Object Oriented Program ...

  7. 剑指Offer(三十七):数字在排序数组中出现的次数

    剑指Offer(三十七):数字在排序数组中出现的次数 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.n ...

  8. 从视频文件中读入数据-->将数据转换为灰度图-->对图像做canny边缘检测-->将这三个结构显示在一个图像中

    //从视频文件中读入数据-->将数据转换为灰度图-->对图像做canny边缘检测-->将这三个结构显示在一个图像中 //作者:sandy //时间:2015-10-10 #inclu ...

  9. 带你轻松玩转Git--图解三区结构

    在上篇文章的结尾我们提到了Git 的三区结构,在版本控制体系中有这样两种体系结构,一种是两区结构一种是三区结构.接下来我们通过对Git三区的结构学习来帮助我们更好的去理解并运用Git. 两区结构是其他 ...

  10. DeepLearning.ai学习笔记(三)结构化机器学习项目--week2机器学习策略(2)

    一.进行误差分析 很多时候我们发现训练出来的模型有误差后,就会一股脑的想着法子去减少误差.想法固然好,但是有点headlong~ 这节视频中吴大大介绍了一个比较科学的方法,具体的看下面的例子 还是以猫 ...

随机推荐

  1. 一个无锁消息队列引发的血案(六)——RingQueue(中) 休眠的艺术 [续]

    目录 (一)起因 (二)混合自旋锁 (三)q3.h 与 RingBuffer (四)RingQueue(上) 自旋锁 (五)RingQueue(中) 休眠的艺术 (六)RingQueue(中) 休眠的 ...

  2. device-pixel-radio

    移动web开发之像素和DPR 今天看到一个面试题,为iphone6s的自适应,答案是@media(min-device-width:414px) and(max-device-width:736px) ...

  3. Java基础90 MySQL触发器

    1.创建触发器 CREATE TRIGGER trigger_name trigger_time trigger_event ON tbl_name FOR EACH ROW trigger_stmt ...

  4. 基于Prometheus的Pushgateway实战

    一.Pushgateway 简介 Pushgateway 是 Prometheus 生态中一个重要工具,使用它的原因主要是: Prometheus 采用 pull 模式,可能由于不在一个子网或者防火墙 ...

  5. Ueditor结合七牛云存储上传图片、附件和图片在线管理的实现和最新更新

    最新下载地址: https://github.com/widuu/qiniu_ueditor_1.4.3 Ueditor七牛云存储版本 注意事项 老版本请查看 : https://github.com ...

  6. hdu 1166 线段树(单点增减 区间求和)

    Sample Input1101 2 3 4 5 6 7 8 9 10Query 1 3Add 3 6Query 2 7Sub 10 2Add 6 3Query 3 10End Sample Outp ...

  7. HTML、CSS、JS 样式 (未整理)

    随手记,有错误的地方希望留言 ^.-.^ PHP 实现关闭浏览器窗口echo "<script>window.close();</script>"; jqu ...

  8. AngularJs指令配置参数scope详解

    AngularJs最重要也是最难理解的模块之一就是它的指令(directive)了,自定义指令配置有很多个参数,下面我只说说其中scope的配置极其含义. scope表示指令的作用域,它有三个可选值: ...

  9. java数组反射实现动态的判断一个对象是否是数组并且对数组进行拆包输出

    public static Map<String, String> maptoMapString(Map<String, ?> map) { return map.entryS ...

  10. 利用transform的bug使fixed相对于父级定位

    首先,大家都清楚,元素使用fixed之后,若不设置top与left则会相对于最近的使用定位的父元素,并位于父元素的原点位置设置top与left值时,则会相对于窗口定位.但无论如何,此时仍相对于窗口定位 ...