项目作者: arogozine

项目描述 :
Generic C# Enum Utilities
高级语言: C#
项目地址: git://github.com/arogozine/EnumUtilities.git
创建时间: 2015-08-10T01:55:43Z
项目社区:https://github.com/arogozine/EnumUtilities

开源协议:The Unlicense

下载


Enum Utilities

Generic Enum Utility for .NET Standard

  • This library provides generic type safe enum operations - something that the Enum class lacks.
  • Written because the .NET HasFlag function for an enumeration is very slow and does type checking AT RUNTIME.
  • Supports all enumeration types from Byte to UInt64

API

Type Safe Wrappers

  1. // Enum.GetUnderlyingType(typeof(T))
  2. Type underlyingType = EnumUtil<YourEnum>.GetUnderlyingType();
  3. // Enum.GetName(typeof(T), value)
  4. string nameFoo = EnumUtil<YourEnum>.GetName(YourEnum.Foo);
  5. // (T)Enum.Parse(typeof(T), value)
  6. YourEnum valueFoo = EnumUtil<YourEnum>.Parse("Foo");
  7. // (T)Enum.Parse(typeof(T), value, ignoreCase)
  8. YourEnum valueFoo2 = EnumUtil<YourEnum>.Parse("foo", ignoreCase: true);
  9. // (T[])typeof(T).GetEnumValues()
  10. YourEnum[] values = EnumUtil<YourEnum>.GetValues();
  11. // typeof(T).GetEnumNames()
  12. string[] names = EnumUtil<YourEnum>.GetNames();
  13. // Enum.TryParse(value, out result)
  14. YourEnum possibleValue;
  15. bool success = EnumUtil<YourEnum>.TryParse("foob", out possibleValue);
  16. // Enum.TryParse(value, ignoreCase, out result)
  17. YourEnum possibleValue2;
  18. bool sucess2 = EnumUtil<YourEnum>.TryParse("foo", true, out possibleValue2);
  19. // Enum.IsDefined(typeof(T), name)
  20. bool isDef2 = EnumUtil<YourEnum>.IsDefined("Foo");

Bitwise Operations

  1. // a | b
  2. YourEnum fooOrBar = EnumUtil<YourEnum>.BitwiseOr(YourEnum.Foo, YourEnum.Bar);
  3. // a & b
  4. YourEnum fooAndBar = EnumUtil<YourEnum>.BitwiseAnd(YourEnum.Foo, YourEnum.Bar);
  5. // a ^ b
  6. YourEnum fooXorBar = EnumUtil<YourEnum>.BitwiseExclusiveOr(YourEnum.Foo, YourEnum.Bar);
  7. // ~ a
  8. YourEnum notBar = EnumUtil<YourEnum>.BitwiseNot(YourEnum.Bar);

[Flag] Operations

  1. // Has Flag?
  2. bool hasFlag = EnumUtil<YourEnum>.HasFlag(YourEnum.Foo | YourEnum.Bar, YourEnum.Bar);
  3. // Set Flag
  4. YourEnum barSet = EnumUtil<YourEnum>.SetFlag(default(YourEnum), YourEnum.Bar);
  5. // Unset (Remove) Flag
  6. YourEnum barUnset = EnumUtil<YourEnum>.UnsetFlag(barSet, YourEnum.Bar);
  7. // Toggle Flag On / Off
  8. YourEnum fooSet = EnumUtil<YourEnum>.ToggleFlag(barUnset, YourEnum.Foo);
  9. // Toggle Flag based on a passed in boolean
  10. YourEnum fooUnset = EnumUtil<YourEnum>.ToggleFlag(fooSet, YourEnum.Foo, false);
  11. // Checks whether the FlagsAttribute it defined on the Enum
  12. // Note: Toggle, Set, Unset, and HasFlag functions do not ensure that
  13. // FlagsAttribute is defined
  14. bool hasFlagsShortcut = EnumUtil<YourEnum>.HasFlagsAttribute();

Is Defined

  1. bool enumValDefined = EnumUtil<YourEnum>.IsDefined((YourEnum)2);
  2. bool enumNameDefined = EnumUtil<YourEnum>.IsDefined("Foo");
  3. // Passed in number types get converted automatically
  4. // to the correct underlying type
  5. // unlike the vanilla Enum.IsDefined which throws an exception
  6. bool byteValDefined = EnumUtil<YourEnum>.IsDefined((byte)2);
  7. bool sbyteValDefined = EnumUtil<YourEnum>.IsDefined((sbyte)2);
  8. bool shortValDefined = EnumUtil<YourEnum>.IsDefined((short)2);
  9. bool ushortValDefined = EnumUtil<YourEnum>.IsDefined((ushort)2);
  10. bool intValDefined = EnumUtil<YourEnum>.IsDefined((int)2);
  11. bool uintValDefined = EnumUtil<YourEnum>.IsDefined((uint)2);
  12. bool longValDefined = EnumUtil<YourEnum>.IsDefined((long)2);
  13. bool ulongValDefined = EnumUtil<YourEnum>.IsDefined((ulong)2);
  14. bool floatValDefined = EnumUtil<YourEnum>.IsDefined((float)2);
  15. bool doubleValDefined = EnumUtil<YourEnum>.IsDefined((double)2);

Conversion From A Number Type

  1. YourEnum val0 = EnumUtil.FromByte<YourEnum>(2);
  2. YourEnum val1 = EnumUtil.FromSByte<YourEnum>(2);
  3. YourEnum val2 = EnumUtil.FromInt16<YourEnum>(2);
  4. YourEnum val3 = EnumUtil.FromUInt16<YourEnum>(2);
  5. YourEnum val4 = EnumUtil.FromInt32<YourEnum>(2);
  6. YourEnum val5 = EnumUtil.FromUInt32<YourEnum>(2);
  7. YourEnum val6 = EnumUtil.FromInt64<YourEnum>(2L);
  8. YourEnum val7 = EnumUtil.FromUInt64<YourEnum>(2UL);
  9. YourEnum val8 = EnumUtil.FromSingle<YourEnum>(2f);
  10. YourEnum val9 = EnumUtil.FromDouble<YourEnum>(2.0);

Conversion To A Number Type

  1. // Conversion from an enum type to a numeric type
  2. byte byteVal = EnumUtil<YourEnum>.ToByte(YourEnum.Foo);
  3. sbyte sbyteVal = EnumUtil<YourEnum>.ToSByte(YourEnum.Foo);
  4. short shortVal = EnumUtil<YourEnum>.ToInt16(YourEnum.Foo);
  5. ushort ushortVal = EnumUtil<YourEnum>.ToUInt16(YourEnum.Foo);
  6. int intVal = EnumUtil<YourEnum>.ToInt32(YourEnum.Foo);
  7. uint uintVal = EnumUtil<YourEnum>.ToUInt32(YourEnum.Bar);
  8. long longVal = EnumUtil<YourEnum>.ToInt64(YourEnum.Foo);
  9. ulong ulongVal = EnumUtil<YourEnum>.ToUInt64(YourEnum.Foo);
  10. float floatVal = EnumUtil<YourEnum>.ToSingle(YourEnum.Bar);
  11. double doubleVal = EnumUtil<YourEnum>.ToDouble(YourEnum.Bar);

Reflected Information

  1. // Shortcut for typeof(T).GetFields(BindingFlags.Public | BindingFlags.Static)
  2. FieldInfo[] fields = EnumUtil<YourEnum>.GetEnumFields();
  3. // On the Enumeration itself
  4. FlagsAttribute attr = EnumUtil<YourEnum>.GetAttribute<FlagsAttribute>();
  5. IEnumerable<DescriptionAttribute> attrs = EnumUtil<YourEnum>.GetAttributes<DescriptionAttribute>();
  6. bool hasFlagsAttr = EnumUtil<YourEnum>.HasAttribute<FlagsAttribute>();
  7. bool hasFlagsShortcut = EnumUtil<YourEnum>.HasFlagsAttribute();
  8. // On a field in the enumeration
  9. DescriptionAttribute attr2 = EnumUtil<YourEnum>.GetAttribute<DescriptionAttribute>(YourEnum.Bar);
  10. IEnumerable<DescriptionAttribute> attrs3 = EnumUtil<YourEnum>.GetAttributes<DescriptionAttribute>(YourEnum.Bar);
  11. // Various Read Only Dictionaries
  12. // with data about the members of an enumeration
  13. var valueDescription = EnumUtil<YourEnum>.GetValueDescription();
  14. var valueNameDescription = EnumUtil<YourEnum>.GetValueNameDescription();
  15. var valueNameAttributes = EnumUtil<YourEnum>.GetValueNameAttributes();
  16. var nameValueAttribute = EnumUtil<YourEnum>.GetNameValueAttribute<DescriptionAttribute>();
  17. var valueNameAttribute = EnumUtil<YourEnum>.GetValueNameAttribute<DescriptionAttribute>();
  18. var valueAttribute = EnumUtil<YourEnum>.GetValueAttribute<DescriptionAttribute>();
  19. var nameValue = EnumUtil<YourEnum>.GetNameValue();
  20. var valueName = EnumUtil<YourEnum>.GetValueName();

Usage with Generics

With C# 7.3

  1. // C# 7.3
  2. private static void YourFunction<TEnum>()
  3. where TEnum : struct, Enum, IComparable, IFormattable, IConvertible
  4. {
  5. // Call EnumUtilBase within the function
  6. TEnum[] values = EnumUtil<TEnum>.GetValues();
  7. // Your Code Here
  8. }

With F

  1. [<Flags>]
  2. type FSFlagsEnum =
  3. | One = 1
  4. | Two = 2
  5. | Fourt = 4
  6. | Eight = 8
  7. let isFlagsEnum<'enum when 'enum : (new : unit -> 'enum) and 'enum : struct and 'enum :> Enum>() =
  8. EnumUtil.HasFlagsAttribute<'enum>()
  9. let bitWiseOr a b = EnumUtil.BitwiseOr(a, b)
  10. let three = bitWiseOr FSFlagsEnum.One FSFlagsEnum.Two

FAQ

1. How does the library work?

Constraints

The library uses C# 7.3 ability to constrain a generic to an Enum.

Functions

Many functions are just type safe wrappers aroung the built-in Enum class.
Others use Expressions (see below) or simple reflection.

Bitwise Operations

In .NET languages ClassName<int> and ClassName<double> do not share static state.
Enum Utilities uses this fact to generate and compile bitwise expressions in the static initializer.
An expression is created that casts down your enumeration to its underLying type (usually Int32).
So the bitwise operation happen on the underlying type. The compiled expression is then stored in a
static readonly field.

2. Can I use this with an enumeration of type (byte, long, short, …)?

Yes. The library supports all types of enumerations. See “Bitwise Operations” above.

3. Are there any functional differences between the built-in HasFlag(..) and your HasFlag?

Enum Utilities does not check for FlagsAttribute.

Installation

To use in your project, install the
EnumUtilities
package.