2011-12-15 30 views
0

我們目前正在開發一個需要處理各種資產的應用程序(C#,.Net 4.0)。爲了追蹤資產的狀態,我們開發了一個「AssetState」類,它返回的各種狀態的資產可以是:處理對象狀態的適當方法?

/// <summary> 
/// Represents the states an asset can be in. 
/// </summary> 
public class AssetState 
{ 
    /// <summary> 
    /// Initializes a new instance of the <see cref="AssetState"/> class. 
    /// </summary> 
    public AssetState() 
    { 
    } 

    #region Properties 

    /// <summary> 
    /// Gets a normal asset state. 
    /// </summary> 
    public static AssetState None 
    { 
     get 
     { 
      return new AssetState(); 
     } 
    } 

    /// <summary> 
    /// Gets a dirty asset state. 
    /// </summary> 
    public static AssetState Dirty 
    { 
     get 
     { 
      return new AssetState(); 
     } 
    } 

    (etc...) 

    #endregion Properties 

    #region Methods 

    /// <summary> 
    /// Overloaded operator used to combine two states into a new one. 
    /// </summary> 
    /// <param name="leftOperandState">The left operand in the equation.</param> 
    /// <param name="rightOperandState">The right operand in the equation.</param> 
    /// <returns>A new asset state, which is the AND combination of both operands, in the form of a list of states.</returns> 
    public static List<AssetState> operator &(AssetState leftOperandState, AssetState rightOperandState) 
    { 
     if (leftOperandState == None && rightOperandState != None) 
     { 
      return new List<AssetState> { rightOperandState }; 
     } 

     if (leftOperandState != None && rightOperandState == None) 
     { 
      return new List<AssetState> { leftOperandState }; 
     } 

     if (leftOperandState == None && rightOperandState == None) 
     { 
      return new List<AssetState> { leftOperandState }; 
     } 

     return new List<AssetState> { leftOperandState, rightOperandState }; 
    } 

    /// <summary> 
    /// Overloaded operator used to combine two states into a new one. 
    /// </summary> 
    /// <param name="leftOperandStates">The left operand in the equation.</param> 
    /// <param name="rightOperandState">The right operand in the equation.</param> 
    /// <returns>A new asset state, which is the AND combination of both operands, in the form of a list of states.</returns> 
    public static List<AssetState> operator &(List<AssetState> leftOperandStates, AssetState rightOperandState) 
    { 
     var newAssetState = new List<AssetState>(); 

     newAssetState.AddRange(leftOperandStates); 
     newAssetState.Add(rightOperandState); 

     return newAssetState; 
    } 

    #endregion Methods 
} 

「資產」類將包含AssetStates的列表。因此,例如,項目可以被標記爲「髒」和「簽出」。當我們需要確定資產的狀態時,我們只需遍歷該列表並確定是否存在特定狀態(或狀態集合)。

In the Asset Class: 

    /// <summary> 
    /// Method which determines if the asset is in a particular state. 
    /// </summary> 
    public bool IsInState(AssetState assetState) 
    { 
     return States.Contains(assetState); 
    } 

    /// <summary> 
    /// Method which determines if the asset is in a particular combination of states. 
    /// </summary> 
    public bool IsInStates(IEnumerable<AssetState> assetStates) 
    { 
     if (assetStates == null) 
     { 
      throw new ArgumentNullException("assetStates"); 
     } 

     // Determine if this asset is in all the states requested. 
     return assetStates.All(assetState => assetState != null && this.IsInState(assetState)); 
    } 

有沒有更好的方法來解決這個問題?我們開發的系統中是否存在重大缺陷,我們忽略了這個缺陷? (同時請記住,這裏的代碼不是最終的,而是一個粗略的草案)。

+1

增加值使用鏈表應該沒問題,如果只有少數幾個州每個對象,但如果一個對象可以有許多狀態(也許幾十個),那麼你會想要某種基於散列或基於二叉樹的解決方案。 – 2011-12-15 14:41:44

+0

狀態列表是否是動態的,或者是否存在給定資產可以擁有的已知和固定的一組狀態? – Maess 2011-12-15 14:43:22

+0

感謝您的輸入。我們估計資產約有4-5個州。狀態列表是固定的和已知的,並且將在AssetState類中以靜態屬性的形式進行硬編碼(至少,這是初始計劃)。 – 2011-12-15 14:46:01

回答

5

看起來你最好使用帶有Flags屬性的枚舉。看看here

使用Flags屬性,您將可以使用&和|運營商。這裏是一個例子:

// make a dirty & checked-out state 
AssetState state = AssetState.Dirty | AssetState.CheckedOut; 

// check if state contains Dirty 
if ((state & AssetState.Dirty) != 0) 
{ 
    // handle the dirty state 
} 

要小心你分配給你的枚舉值。他們應該是1,2,4,8,16等,否則你將無法使用邏輯運算符正確地組合它們。

3

對於如此少數可能的狀態進行組合,請使用enum而不是類。

[Flags] 
enum AssetState 
{ 
    None = 0, 
    Dirty = 1, 
    CheckedOut = 2, 
    RequiresAudit = 4 
} 
//Create new state for checked out and requires audit 
AssetState state = AssetState.CheckedOut | AssetState.RequiresAudit; 
//Set dirty without changing rest of state: 
state |= AssetState.Dirty; 
//Check if is "dirty": 
bool isDirty = (state & AssetState.Dirty) != AssetState.None; 
//Check if is "dirty" alternative method: 
bool isDirty = state.HasFlag(AssetState.Dirty); 

你也可以共同組合,以枚舉的定義,如CheckedOutAndDity = 3

相關問題