CloudyWing.Enumeration
0.2.0
dotnet add package CloudyWing.Enumeration --version 0.2.0
NuGet\Install-Package CloudyWing.Enumeration -Version 0.2.0
<PackageReference Include="CloudyWing.Enumeration" Version="0.2.0" />
<PackageVersion Include="CloudyWing.Enumeration" Version="0.2.0" />
<PackageReference Include="CloudyWing.Enumeration" />
paket add CloudyWing.Enumeration --version 0.2.0
#r "nuget: CloudyWing.Enumeration, 0.2.0"
#:package CloudyWing.Enumeration@0.2.0
#addin nuget:?package=CloudyWing.Enumeration&version=0.2.0
#tool nuget:?package=CloudyWing.Enumeration&version=0.2.0
Enumeration
Enumeration 為Constants 重新優化的版本,起因是看到 MSDN「使用列舉類別,而非列舉類型」這篇文章,覺得原本的命名有些不適當,所以重建一個 Repository,後面不知不覺就幾乎整個重寫了...。
Enumeration,為將列舉類別重複的程式碼整理成 EnumerationBase<T> 的抽象類別,繼承實作的方法請參考 Examples。
Supported Frameworks
- .NET Standard 2.0
- .NET Framework 4.5
- .NET 10
Abstract Enumerations
目前提供以下 Abstract Enumerations 提供繼承:
- EnumerationBase:最底層的 Abstract Enumeration,如
Guid之類未實作IConvertible,可繼承此 Enumeration。 - ConvertibleEnumeration:有實作
IConvertible的 Enumeration,可用在需要IConvertible轉型的地方,如SqlParameter之類的DbParameter有設定DbType時,會使用IConvertible將 Value 轉換成對應型別。 - Numeric Enumerations:此類 Enumeration 皆有繼承
ConvertibleEnumeration與有指定 Value Type,並且在使用==、!=、>、<、>=、<=和Equals等 Operator 和 Method 時,Enumeration 與數值型別的執行結果,大致等同於 Value 與數值型別的執行結果,目前有定義以下 Numeric Enumerations:- CharEnumeration。
- ByteEnumeration。
- SByteEnumeration。
- ShortEnumeration。
- UShortEnumeration。
- IntEnumeration。
- UIntEnumeration。
- LongEnumeration。
- ULongEnumeration。
- FloatEnumeration。
- DoubleEnumeration。
- DecimalEnumeration。
Examples 與簡單的 API 說明
以下範例的 TEnum 表示實際的 Enumeration 型別,TValue 表示 Value 型別。
實作 Enumeration
簡單寫法
/// int 可替換任何 implement IConvertible 的 type
[Serializable]
public sealed class WeekDay : ConvertibleEnumeration<WeekDay, int> {
// Constructor 設定成 private
private WeekDay(int value, string name, string englishName) : base(value, name) {
EnglishName = englishName;
}
public static WeekDay Sunday { get; } = new WeekDay(0, "星期日", nameof(Sunday));
public static WeekDay Monday { get; } = new WeekDay(1, "星期一", nameof(Monday));
public static WeekDay Tuesday { get; } = new WeekDay(2, "星期二", nameof(Tuesday));
public static WeekDay Wednesday { get; } = new WeekDay(3, "星期三", nameof(Wednesday));
public static WeekDay Thursday { get; } = new WeekDay(4, "星期四", nameof(Thursday));
public static WeekDay Friday { get; } = new WeekDay(5, "星期五", nameof(Friday));
public static WeekDay Saturday { get; } = new WeekDay(6, "星期六", nameof(Saturday));
// 額外擴充的 Property
public string EnglishName { get; }
}
使用 Lazy Initialization
/// int 可替換任何 implement IConvertible 的 type
[Serializable]
public sealed class WeekDay : ConvertibleEnumeration<WeekDay, int> {
public static readonly Lazy<WeekDay> sunday = new Lazy<WeekDay>(() => new WeekDay(0, "星期日", nameof(Sunday)));
public static readonly Lazy<WeekDay> monday = new Lazy<WeekDay>(() => new WeekDay(1, "星期一", nameof(Monday)));
public static readonly Lazy<WeekDay> tuesday = new Lazy<WeekDay>(() => new WeekDay(2, "星期二", nameof(Tuesday)));
public static readonly Lazy<WeekDay> wednesday = new Lazy<WeekDay>(() => new WeekDay(3, "星期三", nameof(Wednesday)));
public static readonly Lazy<WeekDay> thursday = new Lazy<WeekDay>(() => new WeekDay(4, "星期四", nameof(Thursday)));
public static readonly Lazy<WeekDay> friday = new Lazy<WeekDay>(() => new WeekDay(5, "星期五", nameof(Friday)));
public static readonly Lazy<WeekDay> saturday = new Lazy<WeekDay>(() => new WeekDay(6, "星期六", nameof(Saturday)));
// Constructor 設定成 private
private WeekDay(int value, string name, string englishName) : base(value, name) {
EnglishName = englishName;
}
public static WeekDay Sunday => sunday.Value;
public static WeekDay Monday => monday.Value;
public static WeekDay Tuesday => tuesday.Value;
public static WeekDay Wednesday => wednesday.Value;
public static WeekDay Thursday => thursday.Value;
public static WeekDay Friday => friday.Value;
public static WeekDay Saturday => saturday.Value;
// 額外擴充的 Property
public string EnglishName { get; }
}
繼承 Numeric Enumeration
[Serializable]
public sealed class WeekDay : IntEnumeration<WeekDay> {
public static readonly Lazy<WeekDay> sunday = new Lazy<WeekDay>(() => new WeekDay(0, "星期日", nameof(Sunday)));
public static readonly Lazy<WeekDay> monday = new Lazy<WeekDay>(() => new WeekDay(1, "星期一", nameof(Monday)));
public static readonly Lazy<WeekDay> tuesday = new Lazy<WeekDay>(() => new WeekDay(2, "星期二", nameof(Tuesday)));
public static readonly Lazy<WeekDay> wednesday = new Lazy<WeekDay>(() => new WeekDay(3, "星期三", nameof(Wednesday)));
public static readonly Lazy<WeekDay> thursday = new Lazy<WeekDay>(() => new WeekDay(4, "星期四", nameof(Thursday)));
public static readonly Lazy<WeekDay> friday = new Lazy<WeekDay>(() => new WeekDay(5, "星期五", nameof(Friday)));
public static readonly Lazy<WeekDay> saturday = new Lazy<WeekDay>(() => new WeekDay(6, "星期六", nameof(Saturday)));
// Constructor 設定成 private
private WeekDay(int value, string name, string englishName) : base(value, name) {
EnglishName = englishName;
}
public static WeekDay Sunday => sunday.Value;
public static WeekDay Monday => monday.Value;
public static WeekDay Tuesday => tuesday.Value;
public static WeekDay Wednesday => wednesday.Value;
public static WeekDay Thursday => thursday.Value;
public static WeekDay Friday => friday.Value;
public static WeekDay Saturday => saturday.Value;
// 額外擴充的 Property
public string EnglishName { get; }
}
條件判斷
由於 Enumeration 無法像 enum 一樣用於 Switch Case,所以提供 Fluent Interface 來簡化寫法。
public void Test(WeekDay week) {
List<WeekDay> list = new List<WeekDay>();
week.When(WeekDay.Sunday).then(() => list.Add(week))
.When(WeekDay.Sunday, WeekDay.Monday).then(() => list.Add(week))
.When(true).then(() => list.Add(week))
.When(WeekDay.Sunday)
.AndWhen(true).then(() => list.Add(week)).then(() => list.Add(week))
.When(WeekDay.Sunday).then(() => list.Add(week))
.OrWhen(WeekDay.Sunday, WeekDay.Monday)).then(() => list.Add(week))
.Default(() => list.Add(week));
/*
以上寫法約等同如下
List<WeekDay> list = new List<WeekDay>();
if (week == WeekDay.Sunday) {
list.Add(week);
} eles if (week == WeekDay.Sunday || week == WeekDay.Monday) {
list.Add(week);
} else if (true) {
list.Add(week);
} else if (week == WeekDay.Sunday && true) {
list.Add(week);
} else if (week == WeekDay.Sunday || (week == WeekDay.Monday || week == WeekDay.Tuesday)) {
list.Add(week);
} else {
list.Add(week);
}
*/
}
Operators
EnumerationBase<TEnum, TValue> 有定義 EnumerationBase<TEnum, TValue> 與 TEnum 還有 EnumerationBase<TEnum, TValue> 與 TValue 之間的 Operators ,Operators 包含了 Implicit Conversion、Explicit Conversion、==、!=、>、<、>=、<=,需注意 Explicit Conversion 失敗會 Throw InvalidCastException。
// i is 1
int i = WeekDay.Monday;
// 因為有可能會失敗或資訊遺失,所以要使用 `Explicit Conversion`,weekDay is Monday
WeekDay weekDay = (WeekDay)1;
// result is true
bool result = WeekDay.Monday == 1;
// 反過來寫結果相同,result is true
bool result = 1 == WeekDay.Monday;
Static Methods
EnumerationBase<TEnum, TValue> 有定義以下 Static Methods,這邊直接用範例說明,在使用 Parse() 時需注意,若找不到對應的 Enumeration,會 Throw EnumerationNotFoundException,所以非確定 Enumeration 存在時,請使用 TryParse()。
// 取得全部的 `WeekDay` Instance
IEnumerable<WeekDay> weekDays = WeekDay.GetAll();
// 取得全部 Value / Name
IEnumerable<int> values = WeekDay.GetValues();
IEnumerable<string> names = WeekDay.GetNames();
// isDefined is true
bool isDefined = WeekDay.IsDefined(1);
// parsedDay is Monday
WeekDay parsedDay = WeekDay.Parse(1);
// 若找不到就回傳指定的預設值,fallbackByValue is Sunday
WeekDay fallbackByValue = WeekDay.ParseOrDefault(9, WeekDay.Sunday);
// foundByValue is true,dayByValue is Monday
bool foundByValue = WeekDay.TryParse(1, out WeekDay dayByValue);
// dayByName is Monday
WeekDay dayByName = WeekDay.ParseName("Monday");
// 可傳入參數來忽略大小寫,dayByNameIgnoreCase is Monday
WeekDay dayByNameIgnoreCase = WeekDay.ParseName("monday", true);
// 若找不到就回傳指定的預設值,fallbackByName is Sunday
WeekDay fallbackByName = WeekDay.ParseNameOrDefault("Holiday", WeekDay.Sunday);
// foundByName is true,parsedByName is Monday
bool foundByName = WeekDay.TryParseName("Monday", out WeekDay parsedByName);
// 可傳入參數來忽略大小寫,foundByNameIgnoreCase is true,parsedByNameIgnoreCase is Monday
bool foundByNameIgnoreCase = WeekDay.TryParseName("monday", true, out WeekDay parsedByNameIgnoreCase);
// isDefinedName is true
bool isDefinedName = WeekDay.IsDefinedName("monday", true);
型別判斷
目前提供以下 Type 的 Extension Methods 來取得 Enumeration 的型別資訊:
IsEnumeration():判斷是否有實作IEnumeration<TEnum, TValue>。GetEnumerationTypes():取得IEnumerable<IEnumeration<TEnum, TValue>>。GetEnumerationValueTypes():取得IEnumerable<TValue>。
集合相關的擴充方法
目前 IEnumerable<IEnumeration<TEnum, TValue>> 提供以下 Extension Methods:
ContainsValue(TValue value):判斷集合裡是否有Value和參數value相同的 Enumeration。ContainsName(string name, bool ignoreCase = false):判斷集合裡是否有Name和參數name相同的 Enumeration。TryGetValue(string name, out TValue value)/TryGetValue(string name, bool ignoreCase, out TValue value):依名稱取得對應的Value。TryGetName(TValue value, out string name):依 Value 取得對應的Name。OfValue():取得IEnumerable<TValue>。OfName():取得IEnumerable<string>based on EnumerationName。ToValueArray():取得TValue[]。ToNameArray():取得string[]based on EnumerationName。ToValueList():取得IList<TValue>。ToNameList():取得IList<string>based on EnumerationName。ToDictionary():取得 Key 為 Enumeration Value、Value為 EnumerationName的IDictionary`。ToNameValueDictionary():取得 Key 為 EnumerationName、Value 為 Enumeration Value 的IDictionary。
實際使用時,這些 API 很適合拿來做查找表或 UI 選項:
IEnumerable<IEnumeration<WeekDay, int>> days = WeekDay.GetAll();
bool hasMonday = days.ContainsName("monday", ignoreCase: true);
bool foundValue = days.TryGetValue("Friday", out int fridayValue);
bool foundName = days.TryGetName(0, out string firstDayName);
IDictionary<int, string> valueNameMap = days.ToDictionary();
IDictionary<string, int> nameValueMap = days.ToNameValueDictionary();
Documentation
完整文檔請參考:https://cloudywing.github.io/Enumeration/
或查看以下主要文章:
License
This project is MIT licensed.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net45 is compatible. net451 was computed. net452 was computed. net46 was computed. net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.5
- No dependencies.
-
.NETStandard 2.0
- No dependencies.
-
net10.0
- No dependencies.
NuGet packages (2)
Showing the top 2 NuGet packages that depend on CloudyWing.Enumeration:
| Package | Downloads |
|---|---|
|
CloudyWing.SpreadsheetExporter
SpreadsheetExporter 核心函式庫,提供試算表匯出的基底架構。 |
|
|
CloudyWing.Enumeration.Calendars
用來提供 Enumeration 的基底類別。 |
GitHub repositories
This package is not used by any popular GitHub repositories.