我是一个相对的VB.Net菜鸟,我正在边做边学。我确定我之前要问过的问题是10 ^ 19次,但无论代码是什么,我都无法弄清楚如何使用谷歌。这就是......
我们有一个对象模型,其中包含一个或多个Project对象,这些对象由多个Table组成,其中包含具有Fields的行。这导致我们的应用程序中的代码看起来像这样......
Dim theColor As String = Projects(1).Tables(5).Rows(22).Fields(3)
在我们的应用程序中,如果此"调用链中的任何对象"如果不存在,theColor的正确值应为 Nothing * 。这就像Excel一样 - 空行中空单元格的值是vbnull,而不是" Excel已崩溃"。
然而,这不是VB.Net的工作方式。例如,如果Rows(22)不存在,则在Nothing上调用Fields(3)并抛出异常。我的问题是如何最好地处理这个......
1)我可以检查每个值,看看它不是什么,但这导致了大量的代码......
If Projects(1) IsNot Nothing AndAlso Projects(1).Tables(5) AndAlso...
我们有数千这些,这需要的代码量是巨大的。
2)我可以在try / catch中包装所有访问器,但这只是一种不同的(1)
3)我可以拥有每个具有空值的对象的特殊实例。因此,例如,Tables(5)返回NullTable,Row(22)返回NullRow。但这意味着我必须始终使用访问器方法,我不能只查看底层数组。你可能会说好,但遗憾的是我们很多旧代码都是这样做的(是的,呃)。
4)还有其他什么吗?我错过了一些除了我以外的人都知道的魔法吗?
答案 0 :(得分:1)
你可以有一个名为GetField的函数
而不是
Dim theColor As String = Projects(1).Tables(5).Rows(22).Fields(3)
你会有
Dim theColor As String = GetField(1, 5, 22, 3)
Function GetField(ByVal projectIndex As Integer, ByVal tableIndex As Integer, ByVal rowIndex As Integer, byVal fieldIndex As Integer) As Object
If Projects(projectIndex) Is Nothing Then
Return Nothing
End If
If Projects(projectIndex).Tables(tableIndex) Is Nothing Then
Return Nothing
End If
If Projects(projectIndex).Tables(tableIndex).Rows(rowIndex) Is Nothing Then
Return Nothing
End If
If Projects(projectIndex).Tables(tableIndex).Rows(rowIndex).fields(fieldIndex) Is Nothing Then
Return Nothing
End If
Return Projects(projectIndex).Tables(tableIndex).Rows(rowIndex).fields(fieldIndex)
End Function
但我得说...你在做什么看起来很草率。您应该考虑使用具有属性的类。
答案 1 :(得分:0)
你可以编造各种各样的“项目经理”。很难从帖子中知道这是多么可行,但有点像:
Class ProjectManager
Public Property CurrentProject As ProjectThing
Public Property CurrentTable As Integer
Get
Return tblIndex
End Get
Set
If CurrentProject IsNot Nothing Then
If CurrentProject.Tables(value) Is Nothing Then
Throw exception
Else
tblIndex = value
End If
End If
End Set
End Property
' etc
然后使用它来存储项目和/或表的当前引用。所有Is Not Nothing
都可以嵌入那里。
Private myPrj As New ProjectManager
...
myPrj.CurrentProject = Project(1)
myPrj.CurrentTable = 5
随着“经理”对所有人进行所有检查,你不必(很多):
Dim theColor As String = myPrj.Rows(22).Fields(3)
或
Dim theColor As String = myPrj.GetRowValue(22, 3)
它真正要做的是为您存储经过验证的对象引用,并测试那些不值得存储的对象。它可以根据您的需要尽可能深入。即使它真正做的只是封装了那些Is Nothing
/ Is Not Nothing
测试,它也可能会增加一些价值。
Public Function GetRowValue(r As Integer, f as Integer) As Something
If r < CurrentProject.Tables(tblIndex).Rows.Count AndAlso
f < CurrentProject.Tables(tblIndex).Rows(r).Fields.Count Then
Return ...
'or
Public Function GetRowValue(Of T)(r As Integer, f as Integer) As T
指定项目后,它可能会公开有用的属性,如TableCount
。由一些最常用,最重要的Const
定义表示的数据可能会作为属性公开:
' swap a property interface for "3"
Dim theColor As String = myPrj.FooColor(22)
答案 2 :(得分:0)
您可以处理异常:
Dim theColor As String = Nothing
Try
theColor = Projects(1).Tables(5).Rows(22).Fields(3)
Catch
End Try
如果你想这么做&#39;正确&#39;您应该指定您要防范的例外:
Dim theColor As String = Nothing
Try
theColor = Projects(1).Tables(5).Rows(22).Fields(3)
Catch ex As IndexOutOfRangeException
Catch ex As NullReferenceException
End Try