我们目前正在开发一个需要处理各种资产的应用程序(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列表。因此,例如,项目可以被标记为“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));
}
有没有更好的方法来解决这个问题?我们开发的系统是否有任何重大缺陷,我们忽略了这些缺陷? (同时请记住,这里的代码不是最终的,而是草稿)。
答案 0 :(得分:5)
看起来你最好使用带有Flags属性的枚举。看看here。
使用Flags属性,您将能够使用&amp;和|运营商。这是一个例子:
// 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等,否则您将无法使用逻辑运算符正确组合它们。
答案 1 :(得分: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