[英]Best practice to determine the amount of flags contained in a Enum-flag combination?
在某些情況下,當我將Enum傳遞給方法時,我需要處理它是否是單個Enum值,否則它是一個標志組合,為此我編寫了這個簡單的擴展:
Vb.Net:
<Extension>
Public Function FlagCount(ByVal sender As System.[Enum]) As Integer
Return sender.ToString().Split(","c).Count()
End Function
C#(在線翻譯):
[Extension()]
public int FlagCount(this System.Enum sender) {
return sender.ToString().Split(',').Count();
}
用法示例:
Vb.Net:
Dim flags As FileAttributes = (FileAttributes.Archive Or FileAttributes.Compressed)
Dim count As Integer = flags.FlagCount()
MessageBox.Show(flagCount.ToString())
C#(在線翻譯):
FileAttributes flags = (FileAttributes.Archive | FileAttributes.Compressed);
int count = flags.FlagCount();
MessageBox.Show(flagCount.ToString());
我只是想問一下,如果存在一種更直接,更有效的方式,我現在正在做的是避免將標志組合表示為String然后將其拆分。
選項A:
public int FlagCount(System.Enum sender)
{
bool hasFlagAttribute = sender.GetType().GetCustomAttributes(typeof(FlagsAttribute), false).Length > 0;
if (!hasFlagAttribute) // No flag attribute. This is a single value.
return 1;
var resultString = Convert.ToString(Convert.ToInt32(sender), 2);
var count = resultString.Count(b=> b == '1');//each "1" represents an enum flag.
return count;
}
說明:
選項B:
代碼:
public int FlagCount(this System.Enum sender)
{
return sender.GetFlaggedValues().Count;
}
/// <summary>
/// All of the values of enumeration that are represented by specified value.
/// If it is not a flag, the value will be the only value returned
/// </summary>
/// <param name="value">The value.</param>
/// <returns></returns>
public static List<Enum> GetFlaggedValues(this Enum value)
{
//checking if this string is a flagged Enum
Type enumType = value.GetType();
object[] attributes = enumType.GetCustomAttributes(true);
bool hasFlags = enumType.GetCustomAttributes(true).Any(attr => attr is System.FlagsAttribute);
//If it is a flag, add all flagged values
List<Enum> values = new List<Enum>();
if (hasFlags)
{
Array allValues = Enum.GetValues(enumType);
foreach (Enum currValue in allValues)
{
if (value.HasFlag(currValue))
{
values.Add(currValue);
}
}
}
else//if not just add current value
{
values.Add(value);
}
return values;
}
不能讓這一個去。 計算整數位的最佳做法是不轉換為字符串...現在我們都使用高級語言,我們是否失去了使用位的能力? ;)
由於問題是關於最有效的實施,這是我的答案。 我沒有嘗試過度優化它,因為這樣做會讓我感到困惑。 我還使用前面的答案作為基礎,使比較更容易。 有兩種方法,一種用於計數標志,另一種用於提前退出,如果您只想知道它是否有一個標志。 注意:您無法刪除標記屬性檢查,因為標准的非標記枚舉也可以是任何數字。
public static int FlagCount(this System.Enum enumValue){
var hasFlagAttribute = enumValue.GetType().GetCustomAttributes(typeof(FlagsAttribute), false).Length > 0;
if (!hasFlagAttribute)
return 1;
var count = 0;
var value = Convert.ToInt32(enumValue);
while (value != 0){
if ((value & 1) == 1)
count++;
value >>= 1;
}
return count;
}
public static bool IsSingleFlagCount(this System.Enum enumValue){
var hasFlagAttribute = enumValue.GetType().GetCustomAttributes(typeof(FlagsAttribute), false).Length > 0;
if (!hasFlagAttribute)
return true;
var isCounted = false;
var value = Convert.ToInt32(enumValue);
while (value != 0){
if ((value & 1) == 1){
if (isCounted)
return false;
isCounted = true;
}
value >>= 1;
}
return true;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.