如何以编程方式知道当前代码在哪个祖先类中定义?
使用以下代理商代码......
Option Public
Option Declare
%Include "lsprcval.lss" 'defines constants used by GetThreadInfo
Dim gNotesLog As NotesLog
Class MyClass
Sub New
On Error GoTo ErrorSub
gNotesLog.LogAction "Starting " + TypeName(Me) + "." & GetThreadInfo(LSI_THREAD_PROC)
Error 1, "Forced error"
Exit Sub
ErrorSub:
gNotesLog.LogError Err, TypeName(Me) + "." & GetThreadInfo(LSI_THREAD_PROC) & ":" & Erl & " " + Error$
Error Err, Error$ 'throw error
End Sub
End Class
Class MyChildClass As MyClass
Sub New
On Error GoTo ErrorSub
gNotesLog.LogAction "Starting " + TypeName(Me) + "." & GetThreadInfo(LSI_THREAD_PROC)
gNotesLog.LogAction "childish code goes here"
Exit Sub
ErrorSub:
gNotesLog.LogError Err, TypeName(Me) + "." & GetThreadInfo(LSI_THREAD_PROC) & ":" & Erl & " " + Error$
Error Err, Error$ 'throw error
End Sub
End Class
Sub Initialize
Set gNotesLog = New NotesLog("ExampleAgent")
gNotesLog.OpenAgentLog
On Error Resume Next
MakeClass
MakeChildClass
gNotesLog.LogAction "Agent Complete"
End Sub
Sub MakeClass
On Error GoTo ErrorSub
Dim oMyClass As New MyClass
Exit Sub
ErrorSub:
gNotesLog.LogError Err, GetThreadInfo(LSI_THREAD_PROC) & ":" & Erl & " " + Error$
Error Err, Error$ 'throw error
End Sub
Sub MakeChildClass
On Error GoTo ErrorSub
Dim oMyChildClass As New MyChildClass
Exit Sub
ErrorSub:
gNotesLog.LogError Err, GetThreadInfo(LSI_THREAD_PROC) & ":" & Erl & " " + Error$
Error Err, Error$ 'throw error
End Sub
日志输出为:
开始运行代理' StackOverflow'在04/10/2017 02:38:24 PM我不喜欢,因为它有误导性。 "启动MYCHILDCLASS.NEW"并且MyClass.New中的代码记录了以下错误。因为MyClass.New会抛出该错误,MyChildClass.New甚至无法启动!
04/10/2017 02:38:24 PM:启动MYCLASS.NEW
04/10/2017 02:38:24 PM:错误(1):MYCLASS.NEW:8强制错误
04/10/2017 02:38:24 PM:错误(1):MAKECLASS:3强制错误
04/10/2017 02:38:24 PM:开始MYCHILDCLASS.NEW
04/10/2017 02:38:24 PM:错误(1):MYCHILDCLASS.NEW:8强制错误
04/10/2017 02:38:24 PM:错误(1):MAKECHILDCLASS:3强制错误
04/10/2017 02:38:24 PM:代理商完成
Ran LotusScript代码
完成运行代理' StackOverflow'在04/10/2017 02:38:24 PM:
我更愿意看到:
开始运行代理' StackOverflow'在04/10/2017 02:38:24 PM因为这样我就知道哪个类包含错误,以及该对象是从后代类本身定义的。
04/10/2017 02:38:24 PM:启动MYCLASS.NEW
04/10/2017 02:38:24 PM:错误(1):MYCLASS.NEW:8强制错误
04/10/2017 02:38:24 PM:错误(1):MAKECLASS:3强制错误
04/10/2017 02:38:24 PM:开始 MYCLASS(MYCHILDCLASS) .NEW
04/10/2017 02:38:24 PM:错误(1): MYCLASS(MYCHILDCLASS) .NEW:8强制错误
04/10/2017 02:38:24 PM:错误(1):MAKECHILDCLASS:3强制错误
04/10/2017 02:38:24 PM:代理商完成
Ran LotusScript代码
完成运行代理' StackOverflow'在04/10/2017 02:38:24 PM:
我知道最简单的解决方案是将MyClass更改为:
Class MyClass
Sub New
On Error GoTo ErrorSub
Dim sMe As String
sMe = TypeName(Me)
If sMe <> "MYCLASS" Then
sMe = "MYCLASS(" + sMe + ")"
End If
gNotesLog.LogAction "Starting " + sMe + "." & GetThreadInfo(LSI_THREAD_PROC)
Error 1, "Forced error"
Exit Sub
ErrorSub:
gNotesLog.LogError Err, sMe + "." & GetThreadInfo(LSI_THREAD_PROC) & ":" & Erl & " " + Error$
Error Err, Error$ 'throw error
End Sub
End Class
但每个方法中都有硬编码的类名。有没有办法在没有将类名硬编码到字符串中的情况下执行此操作,也不假设每个脚本库一直以其中的一个类命名?
答案 0 :(得分:0)
由于缺乏答案,我决定提供我想出的东西。除了尽可能少的例外,我将每个类都放在自己的脚本库中,并且每个脚本库都使用&#34; DebuggingScripts&#34;我创建的库包含(除其他外):
LogErrorForObject()
函数,用于获取有关错误和信息的信息。调用代码并记录它。我不包括下面的代码,我只想指出它的第五个参数是对象的名称。
我所有其他类继承的DebuggingScriptsObjectBASE
类。该类有以下方法:
Public Function ToString As String
- 返回TypeName(Me)
但可以覆盖。例如,某个类可能希望返回Me.Parent.ToString() + ".Child(" & Me.MyName & ")"
Private Sub subRegisterModuleForToString(sClassName As String)
- 将指定的类名与调用模块(也称为脚本库)相关联。这是从每个类的New
构造函数子调用。
Private Function fsToString_FromCodeClass(sCodeClass As String) As String
- 给定定义代码的类的参数,如果sCodeClass = TypeName(Me)
则返回Me.ToString()
,否则返回sCodeClass + "(" + Me.ToString() + ")"
,例如&#34; SuperClassNameWhereCodeIsDefined(类名)&#34;
Private Function fsToString As String
- 如果调用类的New
子名为Me.subRegisterModuleForToString(ThisClassName$)
,则调用捕获的信息将用于获取类名并将其传递给{ {1}}。否则,只需返回Me.fsToString_FromCodeClass
尽管如此,所有这些都已经完成了。现在,每当我创建一个新类时,我都会确保它扩展Me.ToString()
,然后在DebuggingScriptsObjectBASE
构造函数子中调用Me.subRegisterModuleForToString(*MyClassName*)
。完成后,这些类中的任何日志记录/错误处理都可以使用/传递New
,否则他们会使用Me.fsToString()
(例如我提到的TypeName(Me)
函数的第5个参数。如果代码是在任何对象的超类中定义的,则日志会记录该超类的名称以及该对象的LogErrorForObject
方法返回的任何内容。
我仍然希望找到一个解决方案,我根本不需要对我的班级名称进行硬编码,但只需在每个班级的构造函数子调用{{1足够可接受了。
这是我在DebuggingScriptsObjectBASE对象中提到的代码:
ToString()