CloudyWing.Enumeration 0.2.0

dotnet add package CloudyWing.Enumeration --version 0.2.0
                    
NuGet\Install-Package CloudyWing.Enumeration -Version 0.2.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="CloudyWing.Enumeration" Version="0.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="CloudyWing.Enumeration" Version="0.2.0" />
                    
Directory.Packages.props
<PackageReference Include="CloudyWing.Enumeration" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add CloudyWing.Enumeration --version 0.2.0
                    
#r "nuget: CloudyWing.Enumeration, 0.2.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package CloudyWing.Enumeration@0.2.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=CloudyWing.Enumeration&version=0.2.0
                    
Install as a Cake Addin
#tool nuget:?package=CloudyWing.Enumeration&version=0.2.0
                    
Install as a Cake Tool

Enumeration

License: MIT Build and Deploy Documentation Publish to NuGet

EnumerationConstants 重新優化的版本,起因是看到 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 ConversionExplicit 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 Enumeration Name
  • ToValueArray():取得 TValue[]
  • ToNameArray():取得 string[] based on Enumeration Name
  • ToValueList():取得 IList<TValue>
  • ToNameList():取得 IList<string> based on Enumeration Name
  • ToDictionary():取得 Key 為 Enumeration Value、Value為 EnumerationNameIDictionary`。
  • ToNameValueDictionary():取得 Key 為 Enumeration Name、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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .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.

Version Downloads Last Updated
0.2.0 251 3/27/2026
0.1.0 282 6/19/2023