Enum.GetHashCode()的问题
先说一下,正常如果代码可以定义成枚举,我是比较倾向于定义成枚举的,类似这样:
public enum Gender { /// <summary> /// 男 /// </summary> [Description("男")] Male = 1, /// <summary> /// 女 /// </summary> [Description("女")] Female = 2, /// <summary> /// 其他 /// </summary> [Description("其他")] Other = 3 }
那么,通常,在代码中(例如linq),我倾向于用Enum来强制转为其他类型,这样如果我要增加一个枚举或者修改一个枚举的名字,那么我很容易查到有多少需要修改的地方,所以我对于那种“定义了枚举,却在用的时候写死的,诸如p.Gender=1这类的”代码是很痛恨的,因为如果需要修改,你不知道有多少地方需要修改,所以一般我的用法是:如果需要int,那就
(int)Gender.Male;
这样子用,需要修改的时候,只要改了枚举定义,然后alt+shift+F10即可。。。
说明一下,我们项目里面用的EF+MySQL,MySQL里面的类型定义成了INT(4),这样的话,到了Entity里面映射成的是sbyte类型,那么我们的代码就写成了这样:
public enum Status : sbyte { /// <summary> /// 正常 /// </summary> [Description("正常")] Normal = 1, /// <summary> /// 冻结 /// </summary> [Description("冻结")] Frozen = 2 }
继承自sbyte
在这里说明一下,我们这里用到一个叫QueryBuilder的东西,所以需要加linq查询的条件的时候是这样的:
deviceCondition.Equals(d => d.Status, ((sbyte)Status.Normal).ToString());
但是最初我用的时候不是这样的,当时可能脑子抽了,为了不强制转换,我写成了这样:
deviceCondition.Equals(d => d.Status, Status.Normal.GetHashCode().ToString());
看到了什么区别么?就是GetHashCode(),我在用之前甚至在另外的地方验证了一下,确认Gender.Male.GetHashCode().ToString()返回的是1,是我要的结果,但是等到MySQL查询不出来数据,让我一直以为是那个QueryBuilder的In条件筛选针对DateTime类型的问题,后来才发现,Status.Normal.GetHashCode().ToString()返回的并不是我要的1,而是一个四位的数字的时候,我意识到不是QueryBuilder的问题了。
原来,如果你的Enum没有继承自sbyte的时候,或者继承自Int的时候是没有问题的(Enum默认继承自Int?),但是,当继承自其他类型的时候,就不一定了。。。
最后,以后还是强制转换吧,既可以在编码的时候就暴露出错误,也方便在修改的时候,把用到的地方一次全部修改。。。