枚举组合 - vb.net



我有一个项目在 Vb.net 和Windows表单应用程序与dotnet framework 3.5。我正在使用枚举来存储和处理任务:

Public Enum TaskStatus
none = 0
completed = 2
executing = 4
executed = 8
errors = 16      
uploaded = 32
incomplete = 64  
all =-1
End Enum
Private Function Manage()
Dim ts As TaskStatus = TaskStatus.none
'' Task Performed with Error
ts = TaskStatus.errors Or TaskStatus.executed
'' Task Uploading
ts = ts Or TaskStatus.uploaded
ts = ts Or TaskStatus.completed
CheckStatus(ts)
End Function
Private Function CheckStatus(ByVal ts As TaskStatus)
'' Now i have to check for two or More Enums
'' ts have current values := Error , Executed, Uploaded , Completed
If ts = (TaskStatus.uploaded Or TaskStatus.errors) Then
'' It is not working
End If
If ts = (TaskStatus.executed Or TaskStatus.uploaded Or TaskStatus.completed) Then
'' It is not working
End If
If ts And (TaskStatus.uploaded Or TaskStatus.executed) Then
'' Working, But Not Sure is it correct way ?
End If
If (ts And TaskStatus.completed) = TaskStatus.completed Then
'' Completed 
End If
End Function

由于ts具有当前值 := 错误或执行或上传或已完成。
由于框架 3.5,我无法使用HasFlag

如何比较如果枚举中包含两个或多个特定值,如代码中所述?

要检查两个标志,同时忽略任何其他标志,可能如下所示:

If (ts And (TaskStatus.uploaded Or TaskStatus.errors)) =
(TaskStatus.uploaded Or TaskStatus.errors) Then
' ...
End If

这很丑陋。 一个帮助程序方法会使事情变得更好一些:

Function HasFlags(value As TaskStatus, flags As TaskStatus) As Boolean
Return (value And flags) = flags
End Function
If HasFlags(ts, TaskStatus.uploaded Or TaskStatus.errors) Then
' ...
End If

您可以传入任意数量的标志,只要您要检查。

如果completed位很高,则完成。其他哪些位是高位并不重要。

您可以完成错误,值为 18(已完成 + 错误)。它仍然完整,并且已完成但有错误。

如果您的程序不使用此逻辑,则说明您错误地使用了状态位。

  • 我不明白为什么你会在你的枚举中跳过 1
  • -1 表示all是愚蠢的,因为所有枚举值都应该是所有枚举值的总和

如果你这样定义你的枚举,

Public Enum TaskStatus
completed = 1
executing = 2
executed = 4
errors = 8     
uploaded = 16
End Enum
  • all现在将年满 31 岁
  • incomplete是当TaskStatus.Complete位为 0 时

以下是您可以更好地设计它的方法以及有效的使用示例

Public Enum TaskStatus
completed = 1
executing = 2
executed = 4
errors = 8
uploaded = 16
End Enum
Sub Main()
CheckStatus(TaskStatus.executing + TaskStatus.uploaded)
CheckStatus(TaskStatus.completed + TaskStatus.errors)
CheckStatus(TaskStatus.completed)
CheckStatus(TaskStatus.completed + TaskStatus.executing + TaskStatus.executed + TaskStatus.errors + TaskStatus.uploaded)
Console.ReadLine()
End Sub
Private Sub CheckStatus(ByVal ts As TaskStatus)
Console.WriteLine("TaskStatus value: {0}", ts)
If ts And TaskStatus.completed Then
If ts And TaskStatus.errors Then
Console.WriteLine("completed with errors")
Else
Console.WriteLine("completed without errors")
End If
Else
Console.WriteLine("not completed")
If ts And TaskStatus.executing Then
Console.WriteLine("still executing")
If ts And TaskStatus.uploaded Then
Console.WriteLine("finished uploading")
Else
Console.WriteLine("still uploading")
End If
End If
End If
If ts = 31 Then
Console.WriteLine("you set all the status bits!")
End If
Console.WriteLine()
End Sub

带测试程序的输出:

任务状态值:18
未完成
仍在执行
上传完毕

任务状态值:9
已完成但有错误

任务状态值:已完成
完成且没有错误

任务状态值:31
已完成但有错误
您设置所有状态位!

想想我为什么删除incomplete.每个位代表一个布尔逻辑状态,即它只能是一种或另一种方式。如果你有一个已完成和不完整的位,那么你可能会有一个不合逻辑的状态,其中已完成和不完整都很高,值为 66 + 示例中的任何或所有其他位(除了allnone- 也是我删除它们的原因)。完整和不完整的状态是不确定的,那么为什么要浪费位呢?

执行和执行提供了一个类似的难题,因为并非所有组合都有意义,例如执行 + 执行,即它仍在执行但已完成执行。但这些状态的其他组合是有意义的。看看这个:

|executed: 0             |executed: 1                   |
----------------------------------------------------------------------
executing: 0 |not currently executing |executed, finished executing  |
executing: 1 |currently executing     |executed, still executing ??? |

如果你修复了程序的逻辑,你会发现你不需要两个位。这只是一个迹象,表明其他地方存在问题。

最新更新