Use enumeration in dictionary for key value

Source: Internet
Author: User

Since the introduction of generic in. NET Framework 2.0, the use of collections has created a new situation. First, we do not need to consider whether the type is secure. The use of generics and constraints on generic parameters can fully ensure this. Second, collection elements do not affect the performance of collection traversal and operations because of frequent boxing and unboxing. The two benefits of generics are beyond doubt. InDictionary<Tkey,
In tvalue>, except for strings, we generally use the value type as its key, such as int type. The enumeration type, as a value type, is often used as a key in some cases, especially when bit operations are required. The problem occurs here.

We know that,DictionaryThe key must be a unique identifier, soDictionaryIf the key type does not implement the iequatable interface, the system. Object. Equals () and gethashcode () methods are used to determine whether the values are equal by default. We can look at several types of commonly used keys in. net
Definition in framework:

public sealed class String : IComparable, ICloneable, IConvertible,    IComparable<string>, IEnumerable<string>, IEnumerable,    IEquatable<string>public struct Int32 : IComparable, IFormattable,    IConvertible, IComparable<int>, IEquatable<int>public abstract class Enum : ValueType,    IComparable, IFormattable, IConvertible

Note:EnumThe type definition is different from the first two types. It does not implement the iequatable interface. Therefore, when we useEnumWhen the type is used as the key value,DictionaryThe internal operationEnumType conversion to system. object, which causes boxing generation. Yes, it's hard for us to find this trap.EnumAs
Key value performance bottleneck.

How can we solve this problem? The simplest way isEnumFirst convert to int, and then pass it as the key
Dictionary. Another way is to define a class that implements the iequalitycomparer <t> interface. BecauseDictionaryAn overloaded version of the constructor can receive the iequalitycomparer <t> type and use it to judge the key. The iequalitycomparer <t> interface is defined as follows:

public interface IEqualityComparer<T>{    bool Equals(T x, T y);    int GetHashCode(T obj);}

Unfortunately, we cannot directly provideEnumFor example:

class EnumComparer<TEnum> : IEqualityComparer<TEnum>{    public bool Equals(TEnum x, TEnum y)    {        return (x == y);    }    public int GetHashCode(TEnum obj)    {        return (int)obj;    }}

Because we cannot directly perform the = operation on the generic type and forcibly convert the generic object to the int type. On the Code project, there is an article named accelerating
Enum-Based dictionaries with generic enumcomparer, use reflection. emit to implement the equals () and gethashcode () methods. However, this article provides a better way to useC #
Lambda expressions of 3.0:

public class EnumComparer<T> : IEqualityComparer<T> where T : struct{    public bool Equals(T first, T second)    {        var firstParam = Expression.Parameter(typeof(T), "first");        var secondParam = Expression.Parameter(typeof(T), "second");        var equalExpression = Expression.Equal(firstParam, secondParam);        return Expression.Lambda<Func<T, T, bool>>            (equalExpression, new[] { firstParam, secondParam }).            Compile().Invoke(first, second);    }    public int GetHashCode(T instance)    {        var parameter = Expression.Parameter(typeof(T), "instance");        var convertExpression = Expression.Convert(parameter, typeof(int));        return Expression.Lambda<Func<T, int>>            (convertExpression, new[]{parameter}).            Compile().Invoke(instance);    }}

In this case, we can useDictionaryObject:

public enum DayOfWeek{//...}var dictionary = new Dictionary<DayOfWeek, int>(new EnumComparer<DayOfWeek>());

This approach is more effective than direct use.EnumTypeDictionaryThe key is about eight times faster. Don't you be surprised?

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.