我想很多人會習慣用Enum作為旗標,因為同樣是以邏輯And與邏輯Or運算,會比用Int來的好閱讀,並竟誰會知道1、2、4代表什麼東西,尤其專案更多旗標時更難分辦,用Enum因為可以具名化,以文字來代替數字,很容易就可以了解數字代表的意義,不過在.Net Frameword 4.0之前要對Enum作運算,寫的比較多,較為麻煩,也曾寫過ExtensionMethod來簡化作業,不過.Net Frameword 4.0有內建的,就用內建的吧。
我想很多人會習慣用Enum作為旗標,因為同樣是以邏輯And與邏輯Or運算,會比用Int來的好閱讀,並竟誰會知道1、2、4代表什麼東西,尤其專案更多旗標時更難分辦,用Enum因為可以具名化,以文字來代替數字,很容易就可以了解數字代表的意義,不過在.Net Frameword 4.0之前要對Enum作運算,寫的比較多,較為麻煩,也曾寫過ExtensionMethod來簡化作業,不過.Net Framework 4.0有內建的,就用內建的吧。
範例
如果用Enum旗標,可以很簡單用一個變數記錄,星期的選擇情況
[Flags]
public enum Weekly
{
None = 0,
Sunday = 1,
Monday = 2,
Tuesday = 4,
Wednesday = 8,
Thursday = 16,
Friday = 32,
Saturday = 64
}
var selected = Weekly.Sunday | Weekly.Monday | Weekly.Tuesday;
//要知道selected有沒有包含Monday
//方法1 用== Weekly.Monday也可以
var result = (selected & Weekly.Monday).Equals(Weekly.Monday);
//方法2 自已擴充的ExtenstionMethod
result = selected.Has(Weekly.Monday);
//方法3 .Net Framework 4.0後內建的
result = selected.HasFlag(Weekly.Monday);
/// <summary>
/// 自訂的ExtensionMethod,簡化Enum的比較
/// </summary>
public static bool Has(this Enum source, Enum target)
{
ulong value = Convert.ToUInt64(target);
return (Convert.ToUInt64(source) & value) == value;
}
效能測試
跑100000次比較,所消耗的時間。
結果
用Enum會比用Int多耗一些效能,用Method因為多了轉型,比寫死在Code多耗一些效能。
測試Code
[TestMethod()]
public void 純Int()
{
var flags = 1 | 2;
bool result;
for (int i = 0; i < 100000; i++)
{
result = (flags & 2) == 2;
}
}
[TestMethod()]
public void 方法1()
{
var flags = BindingFlags.CreateInstance | BindingFlags.GetField;
bool result;
for (int i = 0; i < 100000; i++)
{
result = (flags & BindingFlags.GetField) == BindingFlags.GetField;
}
}
[TestMethod()]
public void 方法2()
{
var flags = BindingFlags.CreateInstance | BindingFlags.GetField;
bool result;
for (int i = 0; i < 100000; i++)
{
result = flags.Has(BindingFlags.GetField);
}
}
[TestMethod()]
public void 方法3()
{
var flags = BindingFlags.CreateInstance | BindingFlags.GetField;
bool result;
for (int i = 0; i < 100000; i++)
{
result = flags.HasFlag(BindingFlags.GetField);
}
}
NOTE:
1.Enum有沒有加[FlagsAttribute]是有差異的,可以看參考資料2的範例,ToString的結果會不同。
2.邏輯運算有And、OR、XOR、NOT等等,請參考資料3、4