VB.NET:返回不是函数返回类型实例的对象时没有警告

4
我们有这个:
Friend NotInheritable Class ConcreteGraphFactory
    Inherits AbstractGraphFactory

    Public Shared ReadOnly Instance As New ConcreteGraphFactory()

    Private Sub New()
        MyBase.New()
    End Sub

    Friend Overrides Function Create() As AbstractGraph
        Return New ConcreteGraph()
    End Function    

    Private NotInheritable Class ConcreteGraph
        Inherits AbstractGraph

        Private ReadOnly Question1 As New Question("Why isn't this showing a warning?")

        Public Overrides Function GetRoot() As IRoot
            Return Question1 '<---HERE
        End Function

        Public Sub New()
        End Sub

    End Class

End Class

我有IRoot

Friend Interface IRoot
    Inherits IQuestion
    Function GetContainer() As AbstractGraph
End Interface

最后一个问题是什么?
Public Class Question 
    Implements IQuestion

    ' code....

End Class

为什么VS没有显示警告?问题未实现IRoot...

1
IRootNodeNonAnswerIQuestion 之间是否存在继承链? - Panzercrisis
所有实现 IRoot 接口的类都实现了 IQuestion 接口,但反过来则不一定成立。 - Joseph Nields
1个回答

4
如果你希望编译器在那里报错,那么你需要将选项 strict 设置为 On。你可以在项目属性的编译选项卡上进行设置。或者在包含此代码的文件顶部添加 Option Strict On。以下是一些关于选项 strict 意义的详细页面。

http://support.microsoft.com/en-us/kb/311329

https://msdn.microsoft.com/en-us/library/zcd4xwzs.aspx

Option Strict Off表示Visual Basic编译器不强制执行严格的数据类型。它会尝试进行隐式类型转换,如果无法完成,则会抛出运行时错误。

我原本认为这与IRoot是接口无关,但在尝试后发现确实有关系。如果GetRoot返回一个Question没有继承的类,则即使关闭了Option Strict,您也将收到编译器错误。

关闭Option Strict实际上使某些事情更容易,特别是处理后期绑定的COM对象时。在大多数情况下,编写代码时不必担心类型转换。

然而,这也是许多人不喜欢VB.NET的原因之一。个人而言,在使用它时我很喜欢它,但现在已经过去了足够长的时间,以至于编译器不会为您执行所有严格的类型检查似乎有点奇怪。我总是能够告诉某些VB代码是通过从C#转换工具生成的,因为它会有一堆DirectCast调用,在VB开发人员编写的代码中看不到这些调用。

当C#在2009年推出dynamic关键字时,VB.NET开发人员认为,“嗯。我们一直能够编写不用担心类型的代码。”当然,VB.NET并不同于C#中的dynamic,但许多早期动态代码示例展示了在关闭option strict后您已经可以在VB中完成的事情。

1
为什么关闭它会使编译成功? 是因为它返回一个接口,而不是更完整的实现类型吗? - Panzercrisis
1
@Panzercrisis 感谢你的问题。起初我并没有觉得返回一个接口有什么区别,但事实证明确实有区别。好问题!我已经很久没用 VB 了。 - CoderDennis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接