C# 重写(override)Equals 和 GetHashCode

Equals 和 GetHashCode Equals 每个实现都必须遵循以下约定: 自反性(Reflexive): x.Equals(x) 必须返回 true 对称性(Symmetric): x.Equals(y) 为 true 时,y.Equals(x) 也为 true 传递性(Transitive): 对于任何非 null 的应用值 x, y 和 z,如果 x.Equals(y) 返回 true,并且 y.Equals(z) 也返回true,那么 x.Equals(z) 必须返回 true 一致性(Consistence): 如果多次将对象与另一个对象比较,结果始终相同。只要未修改 x 和 y 的应用对象,x.Equals(y) 连续调用 x.Equals(y) 返回相同的值 非null(Non-null): 如果 x 不是 null,y 为 null,则 x.Equals(y) 必须为 false GetHashCode: 两个相等对象根据 equals 方法比较时相等,那么这两个对象中任意一个对象的 GetHashCode 方法都必须产生同样的整数 在我们未对对象进行修改时,多次调用 GetHashCode 使用返回同一个整数。在同一个应用程序中多次执行,每次执行返回的整数可以不一致 如果两个对象根据 Equals 方法比较不相等时,那么调用这两个对象中任意一个对象的 GetHashCode 方法,不一同的整数。但不同的对象,产生不同整数,有可能提高散列表的性能 以上内容摘自@冯辉 的博客: https://www....

April 2, 2022 · 2 分钟 · Remo

C#中的 explicit 和 implicit 关键字

简单记录一下。 explicit explicit 用于声明必须使用强制转换来调用的用户定义的类型转换运算符。 例如如下类型: public class StringCombine { private readonly string _firstString; private readonly string _secondString; public StringCombine(string firstString, string secondString) { this._firstString = firstString; this._secondString = secondString; } public string Combine() { return $"{_firstString} {_secondString}"; } } 可以看到StringCombine类中有一个Combine()方法,用于将该类中的两个私有成有组合后输出: StringCombine stringCombine = new StringCombine("Hello", "world!"); string newString = stringCombine.Combine(); Console.WriteLine(newString); 如上代码将会输出Hello world!。 现在我们在StringCombine类中添加一段代码: public static explicit operator string(StringCombine stringCombine) { return stringCombine.Combine(); } 这时我们稍稍修改一下上面的代码: StringCombine stringCombine = new StringCombine("Hello", "world!...

January 21, 2020 · 1 分钟 · Remo

【转】C#基础小知识之 yield 关键字

转自博客:一天两天三天 对于yield关键字我们首先看一下 msdn 的解释: 如果你在语句中使用 yield 关键字,则意味着它在其中出现的方法、运算符或 get 访问器是迭代器。 通过使用 yield 定义迭代器,可在实现自定义集合类型的 IEnumerable 和 IEnumerator 模式时无需其他显式类(保留枚举状态的类,有关示例,请参阅 IEnumerator)。 yield是一个语法糖 看 msdn 的解释总是让人感觉生硬难懂。其实 yield 关键字很好理解。首先我们对于性质有个了解。yield 是一个语法糖。既然 yield 是在C#中的一个语法糖,那么就说明yield是对一种复杂行为的简化,就是将一段代码简化为一种简单的形式,方便我们程序员使用。 那么yield到底是对什么行为的简化。我们首先来看一下yield的使用场景。 还是来看msdn上的例子。 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication2 { class Program { static void Main(string[] args) { foreach (int i in Power(2, 8, "")) { Console.Write("{0} ", i); } Console.ReadKey(); } public static IEnumerable<int> Power(int number, int exponent, string s) { int result = 1; for (int i = 0; i < exponent; i++) { result = result * number; yield return result; } yield return 3; yield return 4; yield return 5; } } } 这是msdn上yield的一种使用场景。...

August 16, 2019 · 5 分钟 · Remo

正则表达式之零宽断言

引用自百度百科:零宽断言是正则表达式中的一种方法,正则表达式在计算机科学中,是指一个用来描述或者匹配一系列符合某个句法规则的字符串的单个字符串。 通常我们按照一定规则通过正则表达式匹配一段字符串的时候,我们给出的规则文本也会包含在内,比如以下这个例子,我们要匹配出被“#~”和“~#”包裹的文本: var reg = "#~.*?~#"; var text = "这是一段#~测试~#文字,用来测试#~正则表达式~#。"; var matches = Regex.Matches(text.reg); foreach (Match match in matches) { Console.WriteLine(match); } Console.ReadKey(); 运行以上C#代码,我们将会看到输出的是: #~测试~# #~正则表达式~# 但是有些时候,我们不希望规则文本出现在结果之中。这时候我们就需要用上“零宽断言”了。我们只需稍稍修改一下正则的代码: var reg = "(?<=#~).*?(?=~#)"; 其他代码不变,此时输出的就是: 测试 正则表达式 这里用上的(?<=表达式)和(?=表达式)就是零宽断言中的两种形式,前者称为“零宽度正回顾后发断言”,后者称为“零宽度正预测先行断言”。 以上面的代码为例,零宽度正预测先行断言(即(?=表达式))的规则是先从给出的文本中找到第一个“~#”,然后再回过头看看“~#”前面的文本是否符合“.*”这个规则,如果符合则进行匹配,不符合则查找下一个“~#”,然后再重复以上步骤。 零宽度正回顾后发断言(即(?<=表达式))则正好相反,它是先从要匹配的字符串中的最左端找到“#~”,然后看后面的文本是否符合“.*”这个规则,如果是则匹配,如果不是再去找第二个。 当然,还有“负向零宽后发断言(?<!表达式)”和“负向零宽先行断言 (?!表达式)”两种,这两种是找到第一个不匹配表达式的,然后再去做相应判断。 注意,在Javascript中,不支持后发断言,但是在Chrome浏览器中可以正常使用后发断言,这点需要注意一下,否则在Chrome中测试通过的代码,可能换了FireFox就不行了。

March 17, 2018 · 1 分钟 · Remo

【转】C# 之 匿名方法

转自http://www.cnblogs.com/daxnet/archive/2008/11/12/1687011.html 匿名方法是C# 2.0的语言新特性。首先看个最简单的例子: ...

January 9, 2017 · 2 分钟 · Remo