psu*_*003 7 c# visual-studio-2010 operator-precedence
尝试实现一个GetHashCode覆盖类似于Jon的Skeet的建议,在什么是覆盖System.Object.GetHashCode的最佳算法?我注意到在评估顺序中有一些奇怪的行为,当使用条件运算符对类中的集合属性进行空检查时,会导致语法错误.
考虑以下:
public class Foo
{
public String Name { get; private set; }
public List<String> Bar { get; private set; }
public override Int32 GetHashCode()
{
unchecked
{
int hash = 17;
hash = hash * 23 + this.Name == null ? 0 : this.Name.GetHashCode();
hash = hash * 23 + this.Bar == null ? 0 : this.Bar.GetHashCode();
return hash;
}
}
}
Run Code Online (Sandbox Code Playgroud)
当您收到语法错误时hash = hash * 23 + this.Bar == null ? 0 : this.Bar.GetHashCode();,此代码将无法编译,特别是指向hash * 23 + this.Bar段.
错误是
运算符'+'不能应用于'int'和'System.Collections.Generic.List'类型的操作数
你没有得到相同的错误,hash = hash * 23 + this.Name == null ? 0 : this.Name.GetHashCode();虽然唯一的区别Name是a string和Bar是a List<>.
将整个条件操作包装在一组括号中会删除错误,但这仍然无法解释为什么集合属性的处理方式与字符串属性不同.
是否有一个原因我不知道这导致对不同类型的操作进行不同的评估?
小智 7
区别在于它hash * 23 + this.Name == null是一个有效的表达式,而hash * 23 + this.Bar == null不是.+用于算术和字符串连接,但不用于向列表中添加元素.在这两种情况下,整个hash * 23 + this.... == null都被视为?:操作员的条件.
看看这个功能:
void Crash() {
int hash = 123;
int crash = hash * 23 + this.Name == null ? 0 : this.Name.GetHashCode();
}
Run Code Online (Sandbox Code Playgroud)
它与你的相似 - 我删除了无法编译的部分.
当Name设置为null (演示)时,此功能将以您GetHashCode()想要的方式崩溃.这看起来很奇怪,因为乍一看检查的性能null是存在的.
但是,检查它是错误的null:C#与null整个表达式进行比较:
hash * 23 + this.Name
Run Code Online (Sandbox Code Playgroud)
这是一个有效的字符串连接.
这提供了一个线索,以解决您的"玄机":这是不是说其实Bar是一个集合错误导致编译错误,但事实证明Name是string被错误地避免编译错误.
| 归档时间: |
|
| 查看次数: |
110 次 |
| 最近记录: |