我們都知道,C#中可以使用“|”符號來進行Flags枚舉的並操作。(事實上非Flags枚舉也可以這樣做,因為“|”就是二進位並操作,而任何枚舉都可以轉換成數字。)。但是通常使用“|”操作都是在已知枚舉類型的情況下,比如這樣:
FileAttributes.System | FileAttributes.Hidden
如果需要隱式類型並操作,則需要先把枚舉值統一轉換成數字,然後進行二進位並操作,再轉換回枚舉類型。這裡注意:你可以直接把數字轉換成一個已知的枚舉類型,但是不可以把數字轉換成Enum對象,因為Enum對象的類型是未知的。這裡必須需要的一個方法就是Enum.ToObject。它可以把一個數字轉換成指定類型的枚舉Enum對象。他有兩個參數,第一個是枚舉的類型(Type對象),第二個是數字(int, uint, long, ulong…)。它的第二個參數還有一個object類型的重載,不過其實就是檢查object是否是相應數字類型,然後調用對應類型的ToObject方法。
這樣的話,我們可以定義一個Flags枚舉的隱式類型並操作方法:
static Enum Combine(Type enumType, params Enum[] enums)
{
//參數驗證
if (enumType == null)
throw new ArgumentNullException("enumType");
if (enums == null)
throw new ArgumentNullException("enums");
if (!enumType.IsEnum)
throw new ArgumentException("enumType不是枚舉類型");
if (enums.Length == 0)
throw new ArgumentException("enums不包含任何成員");
//把值統一轉換成long
var longval = Convert.ToInt64(enums[0]);
for (int i = 1; i < enums.Length; i++)
longval = longval | Convert.ToInt64(enums[i]);
return (Enum)Enum.ToObject(enumType, longval);
}
做一個簡單的測試,定義一個Flags枚舉:
[Flags]
enum MyEnum
{
a = 1, b = 2, c = 4
}
執行:
var enumValue = Combine(typeof(MyEnum), MyEnum.b, MyEnum.c);
Console.WriteLine(enumValue);
輸出:
b, c