diff --git a/README.md b/README.md index 3caf81f..31fdcbe 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # FastEnum -FastEnum is **the fastest** enum utilities for C#/.NET. It's designed easy to use like `System.Enum`. And provided methods are all achieved zero allocation and faster than `System.Enum` / `Enums.NET`. +FastEnum is **the fastest** enum utilities for C#/.NET. It's much faster than .NET Core, and also faster than [Enums.NET](https://github.com/TylerBrinkley/Enums.NET) that is similar library. Provided methods are all achieved **zero allocation** and are designed easy to use like `System.Enum`. This library is quite useful to significantly improve your performance because enum is really popular feature. [![Releases](https://img.shields.io/github/release/xin9le/FastEnum.svg)](https://github.com/xin9le/FastEnum/releases) @@ -18,144 +18,135 @@ Intel Core i7-8565U CPU 1.80GHz (Whiskey Lake), 1 CPU, 8 logical and 4 physical ``` +# Support Platform + +- .NET Standard 2.0 -# How to use -Simple to use like following, you don't confuse. The biggest limitation of this library is that it only provides a generics version, however almost cases covered. +# How to use -### Get values +This library super easy to use like `System.Enum` that is standard of .NET. Look below: ```cs //--- FastEnum var values = FastEnum.GetValues(); +var names = FastEnum.GetNames(); +var name = FastEnum.GetName(Fruits.Apple); +var name = Fruits.Apple.ToName(); +var defined = FastEnum.IsDefined(123); +var parse = FastEnum.Parse("Apple"); +var tryParse = FastEnum.TryParse("Apple", out var value); +``` +```cs //--- .NET var values = Enum.GetValues(typeof(Fruits)) as Fruits[]; +var names = Enum.GetNames(typeof(Fruits)); +var name = Enum.GetName(typeof(Fruits), Fruits.Apple); +var name = Fruits.Apple.ToString(); +var defined = Enum.IsDefined(typeof(Fruits), 123); +var parse = Enum.Parse("Apple"); +var tryParse = Enum.TryParse("Apple", out var value); ``` +As you can see, the replacement from `System.Enum` is very easy. You never confuse. -### Get names -```cs -//--- FastEnum -var names = FastEnum.GetNames(); -//--- .NET -var names = Enum.GetNames(typeof(Fruits)); -``` +# More features +There are some functions that are often used for enum, and you can be used more conveniently by including them together. -### Convert to name +## 1. Gets pairwised member information + +Sometimes you want value / name pair of enum. `Member` can be used under such cases. `FieldInfo` is also included, so please use it for reflection code. + ```cs -//--- FastEnum -var name = Fruits.Apple.ToName(); -var name = FastEnum.GetName(Fruits.Apple); +class Member +{ + public TEnum Value { get; } + public string Name { get; } + public FieldInfo FieldInfo { get; } + // etc... +} -//--- .NET -var name = Fruits.Apple.ToString(); -var name = Enum.GetName(typeof(Fruits), Fruits.Apple); +var member = Fruits.Apple.ToMember(); ``` -### Check whether value is defined +## 2. Gets `EnumMemberAttribute.Value` + +I often see the developer using `EnumMemberAttribute` as an alias for field name. So FastEnum provides an API that the value can be quickly obtained from the `EnumMemberAttribute.Value` property. + ```cs -//--- FastEnum -var defined = FastEnum.IsDefined(Fruits.Apple); -var defined = FastEnum.IsDefined(123); -var defined = FastEnum.IsDefined("Apple"); -var defined = Fruits.Apple.IsDefined(); +enum Company +{ + [EnumMember(Value = "Apple, Inc.")] + Apple = 0, +} -//--- .NET -var defined = Enum.IsDefined(typeof(Fruits), Fruits.Apple); -var defined = Enum.IsDefined(typeof(Fruits), 123); -var defined = Enum.IsDefined(typeof(Fruits), "Apple"); +var value = Company.Apple.GetEnumMemberValue(); // Apple, Inc. ``` -### Parse / TryParse -```cs -//--- FastEnum -var value = FastEnum.Parse("Apple"); -var value = FastEnum.Parse("123"); +## 3. Adds multiple label annotations to a field + +Multiple attributes can’t be attached to the same field, since `EnumMemberAttribute` is specified `AllowMultiple = false`. It’s inconvenient and I don’t like it personally, so I often use my own `LabelAttribute` as an alternative. You can use it conveniently as follows, because FastEnum provides this feature. -//--- .NET -var value = Enum.Parse("Apple"); -var value = Enum.Parse("123"); -var value = Enum.Parse(typeof(Fruits), "Apple"); -var value = Enum.Parse(typeof(Fruits), "123"); -``` ```cs -//--- FastEnum -var ok = FastEnum.TryParse("Apple", out var value); -var ok = FastEnum.TryParse("123", out var value); +enum Company +{ + [Label("Apple, Inc.")] + [Label("AAPL", 1)] + Apple = 0, +} -//--- .NET -var ok = Enum.TryParse("Apple", out var value); -var ok = Enum.TryParse("123", out var value); -var ok = Enum.TryParse(typeof(Fruits), "Apple", out var value); -var ok = Enum.TryParse(typeof(Fruits), "123", out var value); +var x1 = Company.Apple.GetLabel(); // Apple, Inc. +var x2 = Company.Apple.GetLabel(1); // AAPL ``` -### Get field member information +# Limitation -```cs -//--- FastEnum -var member = Fruits.Apple.ToMember(); +## 1. Provides only generics API +FastEnum provides only generics version method because of performance reason. `System.Enum` provides `System.Type` argument overload, but that’s too slow because of boxing occuration. If you need to use the method that passes `System.Type` type, please use `System.Enum` version. -//--- .NET -Not supported. -``` +## 2. Can’t parse comma-separated string +`System.Enum.Parse` can parse like following string. I think that it isn’t well known because it is a specification that exists quietly. -### Get `EnumMemberAttribute.Value` ```cs +//--- Assuming there is an enum type like following... +[Flags] enum Fruits { - [EnumMember(Value = "_apple_")] - Apple = 0, + Apple = 1, + Lemon = 2, + Melon = 4, + Banana = 8, } -//--- FastEnum -var value = Fruits.Apple.GetEnumMemberValue(); // _apple_ - -//--- .NET -var type = typeof(Fruits); -var name = Enum.GetName(type, Fruits.Apple); -var info = type.GetField(name); -var attr = info.GetCustomAttribute(); -var value = attr.Value; // _apple_ +//--- Passes comma-separated string +var value = Enum.Parse("Apple, Melon"); +Console.WriteLine((int)value); // 5 ``` +It seems to be a useful function when performing flag processing, but if tries to add such a comma-separated analysis, the overhead will come out, so cutting this feature off makes speed up. I think that in most cases there is no problem, because this feature is rarely used (at least I have NEVER used for 12 years). -### Get label -FastEnum provides the `LabelAttribute` that allows multiple text annotation for each enumeration member. +# Why fast ? -```cs -enum Company -{ - [Label("Apple, Inc.")] - [Label("AAPL", 1)] - Apple = 0, -} +As you might expect, it’s because cached internally. It takes the approach of **Static Type Caching**, so the reading cost is **almost zero**. Based on this, I use techniques for avoiding allocation, and create specialized dictionary for specific key internally. -//--- FastEnum -var label_0 = Company.Apple.GetLabel(); // Apple, Inc. -var label_1 = Company.Apple.GetLabel(1); // AAPL - -//--- .NET -Not supported. -```