在 C# 中,enum 本質上是一種實值型別,主要用於定義一組具名常數。雖然 C# 的枚舉不像 Java 那樣支援在枚舉內部直接定義欄位、建構函式與方法,但我們可以透過類別或結構來模擬類似功能,或是利用擴充方法為枚舉增加行為。本文將探討如何在 C# 中實現帶有關聯資料與行為的枚舉模式。
C# 枚舉的底層型別預設為 int,若需為每個成員附加額外資訊(如名稱、描述),常見做法是使用屬性或字典映射。
using System;
using System.ComponentModel;
public enum Course
{
[Description("張三教授 Core Java")]
CoreJava,
[Description("李四教授 Web 開發")]
Web,
[Description("王五教授 EJB")]
EJB
}
// 取得描述的擴充方法
public static class EnumExtensions
{
public static string GetDescription(this Enum value)
{
var field = value.GetType().GetField(value.ToString());
var attr = (DescriptionAttribute)Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute));
return attr?.Description ?? value.ToString();
}
}
// 使用範例
var course = Course.CoreJava;
Console.WriteLine(course.GetDescription()); // 輸出:張三教授 Core Java
若需要枚舉擁有建構函式、欄位與多型行為,建議採用單例模式的密封類別,這在 C# 中被稱為「Smart Enum」模式。
public abstract class Course
{
// 預先定義的單例實例
public static readonly Course CoreJava = new CoreJavaCourse();
public static readonly Course Web = new WebCourse();
public static readonly Course EJB = new EjbCourse();
protected Course(string teacherName) => TeacherName = teacherName;
public string TeacherName { get; }
// 抽象方法,由各具體實作覆寫
public abstract void Study();
// 私有巢狀類別,確保外部無法繼承
private sealed class CoreJavaCourse : Course
{
public CoreJavaCourse() : base("張三") { }
public override void Study() => Console.WriteLine("Study CoreJava");
}
private sealed class WebCourse : Course
{
public WebCourse() : base("李四") { }
public override void Study() => Console.WriteLine("Study Web");
}
private sealed class EjbCourse : Course
{
public EjbCourse() : base("王五") { }
public override void Study() => Console.WriteLine("Study EJB");
}
}
// 使用方式
Course.CoreJava.Study(); // 輸出:Study CoreJava
Console.WriteLine(Course.Web.TeacherName); // 輸出:李四
enum 適合單純的常數集合,若需攜帶資料或行為,請改用 Smart Enum(單例類別) 模式。