Using GetHashCode for getting Enum int value
Asked Answered
H

7

33

I have an enum

public enum INFLOW_SEARCH_ON
{
  ON_ENTITY_HANDLE = 0,         
  ON_LABEL = 1,                 
  ON_NODE_HANDLE = 2            
} // enum INFLOW_SEARCH_ON

I have to use this enum for searching in a grid column.

To get the column index I am using

  MyEnumVariable.GetHashCode() 

Which works ok, or should I use

  (short)MyEnumVariable

I am a bit confused over using GetHashCode(). Is there any problem using that?

Haematocryal answered 3/1, 2011 at 13:1 Comment(0)
M
63

Using GetHashCode() is incorrect. You should cast to int. Using it the way you do is asking for raptors(or Raymond) to come and eat you.

That GetHashCode() happens to return the integer value of the enum is an implementation detail and may change in future versions of .net.

GetHashCode() guarantees that if two values are equal their hash codes are equal too. The other way round is not guaranteed.

My rule of thumb is that if GetHashCode were to return a constant value your program should still work correctly (but potentially be much slower) since a constant GetHashCode trivially fulfills the contract, but has bad distribution properties.

Mathian answered 3/1, 2011 at 13:10 Comment(2)
Good point but such change is very unlikely because I think there is nothing beneficial to use anything other than default int value of enum. (it would be a breaking change as well)Delitescent
Changing implementation details does not constitute a breaking change. It just means that code that depends on undefined behavior experiences undefined results. As far as beneficiality, you could do much better in terms of distribution than an enum's underlying int value.Debbiedebbra
S
9

When I did profiling, Enum.GetHashCode took a lot of cycles. I was able to improve it by using (int)Enum where possible.

Saritasarkaria answered 5/2, 2013 at 18:11 Comment(0)
I
6

Others have said why casting to int is better.

Another reason to not use GetHashCode is performance. It causes boxing. In my quick tests, GetHashCode was about 50 times slower (if it matters).

Illuminometer answered 10/6, 2013 at 20:14 Comment(0)
Z
5

You should use (int)MyEnumVariable for getting the literal value... you can also convert the other way like (INFLOW_SEARCH_ON)int

Zelazny answered 3/1, 2011 at 13:4 Comment(0)
S
3

You should use (int) MyEnumVariable. All enums by default are inherited from int.

Serotherapy answered 3/1, 2011 at 13:4 Comment(4)
Any severe problems in using GetHashCode()Haematocryal
@CodeInChaos I mean that enum MyEnum { } is equal to enum MyEnum : int { }Serotherapy
@Mohit This method is used to get hash code for hashtables. I believe that using it for conversion to integer is not a best idea, because code looks little bit confusing for other developers. Anyway, I am almost sure, that internal implementation of this method is return (int)Value;Serotherapy
The term you are looking for is "underlying type". And if one is unsure what type was used there is a Enum.GetUnderlyingType method. (Nullable also has this method.)Atlas
S
1

I see some comments that describe the disadvantages of using GetHashCode() for many reasons.

There are some cases where (int)INFLOW_SEARCH_ON.ON_LABEL doesn't work.

A good way to get the int value from Enum is using GeTTypeCode() method. This method works regardlesss of the underlying type. In this case it is int.

public enum INFLOW_SEARCH_ON
{
 ON_ENTITY_HANDLE = 0,         
 ON_LABEL = 1,                 
 ON_NODE_HANDLE = 2            
} // enum INFLOW_SEARCH_ON

INFLOW_SEARCH_ON selectedType = INFLOW_SEARCH_ON.ON_LABEL;

object val = Convert.ChangeType(selectedType, selectedType.GetTypeCode());
Console.WriteLine(val);

Output in this case is '1'.

Reference: Get int value from enum

Shingle answered 26/8, 2014 at 17:16 Comment(1)
In this case the enum type is known at compile time, and you should not expect the underlying type of an enum to change over time; so you can simply cast the enum to whatever the underlying type is, which in this case is int. Were it to be, say, long, then you would simply want to statically cast to that.Stellarator
R
0

You also have the option methods provided by the Enum static class. For instance:

Enum.TryParse<TEnum>(string ValueType, out TEnum Result)

If all you are trying to do is get the value of the Enum. You can get the string ValueType, e.g. "ON_ENTITY_HANDLE" with Enum.GetName(...).

Otherwise, casting to (int) would definitely be preferred over GetHashCode().

Rainband answered 3/1, 2011 at 13:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.