处理对象状态的适当方式?

Hus*_*lil 0 c# algorithm design-patterns

我们目前正在开发一个需要处理各种资产的应用程序(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
}
Run Code Online (Sandbox Code Playgroud)

"资产"类将包含AssetStates列表.因此,例如,项目可以被标记为"Dirty"和"CheckedOut".当我们需要确定资产的状态时,我们只需遍历该列表并确定是否存在特定的状态(或状态集).

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));
    }
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法来解决这个问题?我们开发的系统是否有任何重大缺陷,我们忽略了这些缺陷?(同时请记住,这里的代码不是最终的,而是草稿).

Dan*_*iel 5

看起来你最好使用带有Flags属性的枚举.看看这里.

使用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
}
Run Code Online (Sandbox Code Playgroud)

请注意您为枚举赋值的值.它们应该是1,2,4,8,16等,否则您将无法使用逻辑运算符正确组合它们.