很多C#的教材都会强调对象相等的概念。我们都知道,在C#的世界里存在两种等同性。一种是逻辑等同性:如果两个对象在逻辑上代表同样的值,则称他们具有逻辑等同性。另一种是引用等同性:如果两个引用指向同一个对象实例,则称他们具有引用等同性。
众所周知,Object类型有一个名为Equals的实例方法可以用来确定两个对象是否相等。Object的Equals的默认实现比较的是两个对象的引用等同性。而Object的派生类ValueTpye重写了Equals方法,它比较的是两个对象的逻辑等同性。也就是说,在C#里,引用类型的默认Equals版本关注的是引用等同性,而值类型关注的是逻辑等同性。当然,这并不总能满足我们的要求。所以每当我们更在意引用类型的逻辑等同性的时候,我们就应该重写Equals方法。
重写引用类型的Equals方法以改变其默认的比较方式的一个著名例子是String类。当我们写出string1.Equals(string2)这样的代码时,我们比较的不是string1和string2这两个引用所指向的是否为同一个实例(引用等同性),而是比较string1与string2所包含的字符序列是否相同(逻辑等同性)。
误解一:Equals方法和operator==具有相同的默认行为。
对于引用类型,如果没有为它重载==操作符,且其父类型也没有重写Equals方法,则这个引用类型Equals方法和operator==具有相同的默认行为,即它们比较的都是对象的引用等同性。然而对于值类型来说,就完全不是这么回事了!因为如果你没有为自定义值类型重载operator==的话,就不能写这样的代码myStruct1 == myStruct2,否则会得到一个编译错误,原因是值类型没有相等操作符重载的默认实现。
误解二:自定义类的Equals的方法默认实现将自动调用operator==方法,或operator==方法的默认实现将自动调用Equals方法。
经常听到有人说某某类型是引用类型,所以它的Equals方法的默认实现将自动调用operator==方法。这种说法完全是没有道理的。正如上文所说的,引用类型Equals方法的默认实现来自Object,而值类型的默认实现来自TypeValue,就算他们会使用==操作符,使用的也是Object或TypeValue的重载版本。原则上来说,只要我们没有重写一个类的Equals方法,那么它就会继承其父类的实现,而父类是没有机会使用子类型的操作符重载的。同样,只要我们没有在一个类的==操作符重载中调用Equals方法,它是不会自动调用的。
误解三:值类型的默认Equals实现是对两个对象进行逐位比较的。
有些人认为值类型的Equals默认实现就是通过比较两个对象在内存中的位表示,即如果所有的二进制位都相等,则说明这两个对象等同。这是不准确的。因为其实值类型的Equals默认实现是对值类型的每个字段都调用该字段类型的Equals方法,如果所有字段的Equals方法都返回true,则他们才可能相等。来看一个例子:
class MyClass { public override bool Equals(object obj) { Console.WriteLine("MyClass的Equals方法被调用了。"); return true; } } struct MyStruct { public MyClass Filed; } class Program { staticvoid Main(string[] args) { MyStruct a; MyStruct b; a.Filed = new MyClass(); b.Filed = new MyClass(); Console.WriteLine(a.Equals(b)); } }
很显然,a和b拥有完全不同的二进制位表示。但是最终打印的结果是:
MyClass的Equals方法被调用了。
True
这说明值类型的默认实现是通过调用字段的Equals方法来确定两个对象是否相等,而不是通过比较他们的二进制位是否一致来确定的。
误解四:Equals是非常基本、非常常用的方法,所以其默认的实现不存在性能问题。
对于引用类型,Equals的默认实现很简单,仅仅需要判断两个引用是不是同一种类型、两个引用指向的是不是同一块内存就可以了。所以其性能也没有问题。但是对于值类型,Equals的任务就没有这么简单了。它需要对两个对象的所有字段都做出比较,即逐字段调用字段类型的Equals。由于在ValueType(值类型Equals方法默认实现的位置)中,不可能知道它所有的子类型都包含哪些字段,所以为了调用子类型字段的Equals方法,ValueType的Equals就需要使用反射技术。您可能已经看出来了,反射并不是一种性能友好的技术,所以值类型的Equals方法算不上高效。这也正是为什么微软推荐我们为自定义值类型重写Equals方法的原因。
更多C#初学者对Equals方法的几个常见误解相关文章请关注PHP中文网!

C#和.NET的关系是密不可分的,但它们不是一回事。C#是一门编程语言,而.NET是一个开发平台。C#用于编写代码,编译成.NET的中间语言(IL),由.NET运行时(CLR)执行。

C#.NET依然重要,因为它提供了强大的工具和库,支持多种应用开发。1)C#结合.NET框架,使开发高效便捷。2)C#的类型安全和垃圾回收机制增强了其优势。3).NET提供跨平台运行环境和丰富的API,提升了开发灵活性。

C#.NETisversatileforbothwebanddesktopdevelopment.1)Forweb,useASP.NETfordynamicapplications.2)Fordesktop,employWindowsFormsorWPFforrichinterfaces.3)UseXamarinforcross-platformdevelopment,enablingcodesharingacrossWindows,macOS,Linux,andmobiledevices.

C#和.NET通过不断的更新和优化,适应了新兴技术的需求。1)C#9.0和.NET5引入了记录类型和性能优化。2).NETCore增强了云原生和容器化支持。3)ASP.NETCore与现代Web技术集成。4)ML.NET支持机器学习和人工智能。5)异步编程和最佳实践提升了性能。

c#.netissutableforenterprise-levelapplications withemofrosoftecosystemdueToItsStrongTyping,richlibraries,androbustperraries,androbustperformance.however,itmaynotbeidealfoross-platement forment forment forment forvepentment offependment dovelopment toveloperment toveloperment whenrawspeedsportor whenrawspeedseedpolitical politionalitable,

C#在.NET中的编程过程包括以下步骤:1)编写C#代码,2)编译为中间语言(IL),3)由.NET运行时(CLR)执行。C#在.NET中的优势在于其现代化语法、强大的类型系统和与.NET框架的紧密集成,适用于从桌面应用到Web服务的各种开发场景。

C#是一种现代、面向对象的编程语言,由微软开发并作为.NET框架的一部分。1.C#支持面向对象编程(OOP),包括封装、继承和多态。2.C#中的异步编程通过async和await关键字实现,提高应用的响应性。3.使用LINQ可以简洁地处理数据集合。4.常见错误包括空引用异常和索引超出范围异常,调试技巧包括使用调试器和异常处理。5.性能优化包括使用StringBuilder和避免不必要的装箱和拆箱。

C#.NET应用的测试策略包括单元测试、集成测试和端到端测试。1.单元测试确保代码的最小单元独立工作,使用MSTest、NUnit或xUnit框架。2.集成测试验证多个单元组合的功能,常用模拟数据和外部服务。3.端到端测试模拟用户完整操作流程,通常使用Selenium进行自动化测试。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

禅工作室 13.0.1
功能强大的PHP集成开发环境

记事本++7.3.1
好用且免费的代码编辑器

安全考试浏览器
Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

WebStorm Mac版
好用的JavaScript开发工具

mPDF
mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),