我来自Objective-C背景,我正在编写一些包含委托的VB.NET。我有一个执行某项任务的班级Worker
。此类的一个属性是ILogger
对象,它有一个附加到某个日志文件的方法。 (我希望我的Worker
对象与日志记录分离,这将由我的GUI处理。)在Objective-C中我可以声明
@property (nonatomic, strong) id<LoggingDelegate> logger;
然后用
之类的行撒上我的代码[logger appendToLog:@"Beginning polarity reversal..."];
在Objective-C中,logger
实际上并不需要设置为一个对象才能工作;如果它是一个空引用(Objective-C中的“nil”),运行时将忽略appendToLog:
消息。
在VB.NET中我可以做类似的事情:
Public Property logger As ILogger
和
logger.AppendText("Beginning polarity reversal...")
但是,当然,logger
实际上需要设置为一个对象才能使其工作。什么是处理我没有附加到我的工作者的记录器对象的情况的惯用方法? (更一般地说,我在VB.NET中实现了委托模式惯用语吗?)
答案 0 :(得分:4)
每次使用可选对象时,都可以先检查它是否为null,例如:
If logger IsNot Nothing Then
logger.AppendText("Beginning polarity reversal...")
End If
或者,您可以创建一个私有方法,为您执行额外检查:
Private Sub AppendTextToLog(text As String)
If logger IsNot Nothing Then
logger.AppendText("Beginning polarity reversal...")
End If
End Sub
或者,正如推荐的vcsjones,您可以将属性默认为虚拟对象:
Public Class MyClass
Private Class DummyLogger
Implements ILogger
Public Sub AppendText(text As String) Implements ILogger.AppendText
' Do nothing
End Sub
End Class
Public Property Logger As ILogger
Get
Return _logger
End Get
Set(ByVal value As ILogger)
_logger = value
End Set
End Property
Private _logger As ILogger = New DummyLogger()
Public Sub DoWork()
_logger.AppendText("Beginning polarity reversal...")
End Sub
End Class
或者,与VB.NET中“可选委托”最接近的事实上是Event
:
Public Class MyClass
Public Event AppendText(text As String)
Public Sub DoWork()
RaiseEvent AppendText("Beginning polarity reversal...")
End Sub
End Class
从VB 14.0(Visual Studio 2015)开始,您现在可以使用?.
运算符(它称为“空条件”运算符):
logger?.AppendText("Beginning polarity reversal...")
或者,如果您想使用实际的委托,您也可以将同一个运算符与委托一起使用。因此,如果您有一个名为appendToLog
的委托变量,则可以调用:
appendToLog?.Invoke("Beginning polarity reversal...")
答案 1 :(得分:2)
我暂停我的道德信念,指出可以在null对象上调用扩展方法。所以,如果你写:
Module M
<Extension>
Public Sub LogIfNotNull(logger As ILogger, message As String)
If logger IsNot Nothing Then
logger.AppendText(message)
End If
End Sub
End Module
您可以使用此扩展方法写入您的ILogger,它可以执行您想要的操作。现在,我不建议将您的地址放在这段代码附近,因为找到它的下一位开发人员可能想知道您住在哪里。够了。
vcsjones&#39; point是最好的(谁应该把它作为一个答案,所以你可以接受它!):创建一个NullLogger对象并使用它。然后抽象&#34;我不想记录&#34;隐藏在呼叫者之外。