2013-10-29 120 views
3

我需要將具有3個布爾屬性的遺留類轉換爲標誌枚舉。將一些布爾屬性轉換爲標誌枚舉

我知道至少有一個屬性是真的。

[Flags] 
public enum FlagEnum 
{ 
    EnumValue1 = 1, 
    EnumValue2 = 2, 
    EnumValue3 = 4 
} 

public class LegacyClass 
{ 
    public bool PropA { get; set; } 
    public bool PropB { get; set; } 
    public bool PropC { get; set; } 
} 

public class DtoClass 
{ 
    public FlagEnum FlagEnum { get; set; } 

    public DtoClass(LegacyClass legacyClass) 
    { 
     if (!legacyClass.PropA && !legacyClass.PropB && !legacyClass.PropC) 
     { 
      throw new ArgumentException(); 
     } 

     if (legacyClass.PropA) 
     { 
      FlagEnum = FlagEnum.EnumValue1; 
     } 
     if (legacyClass.PropB) 
     { 
      if (legacyClass.PropA) 
      { 
       FlagEnum = FlagEnum.EnumValue1|FlagEnum.EnumValue2; 
      } 
      else 
      { 
       FlagEnum = FlagEnum.EnumValue2; 
      } 
     } 
     if (legacyClass.PropC) 
     { 
      if (legacyClass.PropA||legacyClass.PropB) 
      { 
       FlagEnum = FlagEnum | FlagEnum.EnumValue3; 
      } 
      else 
      { 
       FlagEnum = FlagEnum.EnumValue3; 
      } 
     } 
    } 
} 

還有一個更優雅的或更好的方式來做到這一點考慮比別人可以有更多的屬性,然後標誌設置?

----------------- UPDATE ---------------------------

您的所有解決方案都是有效的,並且非常適合每個人+1。

但我必須選擇一個和我最喜歡的,因爲它是簡潔和可讀的恕我直言是Fredou's

感謝大家!

+1

@BartoszKP FlagEnum = FlagEnum | FlagEnum.EnumValue3; – giammin

+0

@BartoszKP沒問題! :) – giammin

回答

8

這樣的事情呢?

using System; 

namespace ConsoleApplication1 
{ 

    [Flags] 
    public enum FlagEnum 
    { 
     EnumValue1 = 1, 
     EnumValue2 = 2, 
     EnumValue3 = 4 
    } 

    public static class LegacyClass 
    { 
     public static bool PropA { get; set; } 
     public static bool PropB { get; set; } 
     public static bool PropC { get; set; } 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      LegacyClass.PropB = true; 
      FlagEnum result = LegacyClass.PropA ? FlagEnum.EnumValue1 : 0; 
      result |= LegacyClass.PropB ? FlagEnum.EnumValue2 : 0; 
      result |= LegacyClass.PropC ? FlagEnum.EnumValue3 : 0; 
     } 
    } 
} 
1

您是否必須對此使用按位運算?我懷疑非按位的方法將在這裏工作:

FlagEnum = (FlagEnum)(1 * (ToInt(legacyClass.PropA)) 
      + 2 * (ToInt(legacyClass.PropB)) 
      + 4 * (ToInt(legacyClass.PropC))); 

假設我們有一個函數

int ToInt(bool b) { return b ? 1 : 0; } 

它可以更巧妙地做,如果在傳統類的布爾值枚舉 - 那麼我們就可以使用Math.Pow(n,2)應用公式。但這是一個設計選擇。

5

而不是使用在你的代碼分支,你可以做按位運算的小功能相結合,簡化了代碼:

T GetFlag<T>(Boolean value, T flag) { 
    return value ? flag : default(T); 
} 

要計算枚舉值,你可以用這個表達式:

var flagEnum = GetFlag(legacyClass.PropA, FlagEnum.EnumValue1) 
    | GetFlag(legacyClass.PropB, FlagEnum.EnumValue2) 
    | GetFlag(legacyClass.PropC, FlagEnum.EnumValue3); 

請注意,如果沒有設置任何標誌,您的代碼將拋出一個ArgumentException。此代碼將代替計算default(FlagEnum),在本例中爲0.

+0

不會默認(T)總是返回枚舉中的第一個值?如果是這樣,那麼即使傳入的布爾值爲假,該標誌也將始終設置。 – Slavo

+0

當'T'是一個枚舉時,即使枚舉的第一個值不是0,默認(T)'返回'(T)0'。 –

+0

哦,不知道。謝謝。 – Slavo

1

這個怎麼樣?

public DtoClass(LegacyClass legacyClass) 
{ 
    if (!legacyClass.PropA && !legacyClass.PropB && !legacyClass.PropC) 
    { 
     throw new ArgumentException(); 
    } 
    FlagEnum = ((legacyClass.PropA) ? FlagEnum.EnumValue1 : FlagEnum) 
     | ((legacyClass.PropB) ? FlagEnum.EnumValue2 : FlagEnum) 
     | ((legacyClass.PropC) ? FlagEnum.EnumValue3 : FlagEnum); 
}