在 vb.net 中隐式实例化的对象?

8
我是一名有用的助手,可以为您进行文本翻译。以下是需要翻译的内容:

我正在维护一个同时包含VB.NET和C#组件的应用程序。我曾认为这两种语言只是在语法上有所不同,但我发现了VB.NET中一个奇怪的特性,而在C#中并不存在。

在VB.NET中,我有以下类:

Public Class bill_staff Inherits System.Windows.Forms.Form
    ....
End Class

如果我想在C#中使用这个类,我会这样做:
using (var frm = new bill_staff())
    frm.ShowDialog();

然而,在VB.NET代码中,可以像这样使用该类:
bill_staff.ShowDialog();

ShowDialog在元数据中被定义为:

Public Function ShowDialog() As System.Windows.Forms.DialogResult

在VB.NET中,可以在类上调用实例方法。据我所知,这似乎会隐式创建类的新实例,然后调用该对象上的方法。在C#中,这是不可能的-静态方法必须在类上调用,而实例方法必须在对象上调用。
我在互联网上找不到任何关于这个特性的信息。这个特性叫什么名字,这是一个好的实践吗?
该项目最初是从VB6转换而来 - 这是一种奇怪的遗留特性吗?

在调用ShowDialog()之前,您需要创建该类的一个新实例。 - Ric
@Ric 不需要。它可以编译和运行得很好。 - Oliver
考虑到该函数是一个实例方法而不是类方法(即不是共享函数),我觉得这很奇怪...难道没有在其他地方创建对象吗? - Ric
5
是的,这是传统行为。在VB 4之前,类并没有出现过,因此Form.Show是显示表单的方式。因此,为了使以前的代码与旧的方式兼容,仍然合法,但据我所知,它会带来一些开销。实例化是更好的方法。你会看到很多新手在这里使用老的方式,这表明他们还不太理解面向对象编程。 - Ňɏssa Pøngjǣrdenlarp
哇,我刚尝试了一下,你是对的!每天都有新的东西可以学习! - Ric
类似的问题 http://stackoverflow.com/questions/10601503/access-form-property-with-instance-vb-net https://dev59.com/52445IYBdhLWcg3wytEU - MarkJ
2个回答

11

是的,那是旧版行为。在VB4之前,Form1.Show是显示窗体的方式。为了保持先前代码的兼容性(VB3也非常流行),旧方法得到了保留。

.NET仍然支持这种方式来显示窗体。最初,这是为了方便将VB6代码迁移到VB.NET中添加的。但它也是为了让使用VB编程更加轻松-微软称其为您的指尖功能等短语。

基本上,它为业余爱好者提供了一种不需要理解对象和面向对象编程的编程方式。如果Form1.Show引发错误,那么我们这里会有多少问题呢?

显式实例化是更好的方法,因为它是面向对象的,并且使您的代码不太可能引用或创建新的Form2时实际上要使用现有实例。


1
+1. VB6的文档在这里解释了它:(http://msdn.microsoft.com/en-us/library/aa262343(v=vs.60).aspx)。VB.net文档在这里简要提到它,但没有解释它为什么存在(遗留代码)。(http://msdn.microsoft.com/en-us/library/vstudio/87y2hdsf.aspx)。它在这篇VB2005的MSDN技术文章中得到了解释,位于`My.Forms`下面。(http://msdn.microsoft.com/en-us/library/ms379610(v=vs.80).aspx#vbmy_topic3) - MarkJ
@Plutonix -- 你的意思是手动实例化表单更好,因为你认为它会带来一些开销,但是如果你不使用后台.NET为你创建的实例,那么浪费它不是本身就是一种浪费吗?这样做实际上是在做同样的事情两次... - Keith
2
.NET 不会在后台创建实例,当你使用默认实例方法 (Form1.Show) 时 VB 会这么做。因为 Dim frm As New Form1() 只会创建一个窗体实例,所以不会浪费资源。使用默认实例可能会导致许多与作用域有关的问题... - Ňɏssa Pøngjǣrdenlarp
啊,好的。我曾经是一名C++程序员。自从我意识到表单(或者至少我认为)在加载时是自动创建的后,我已经有一段时间只使用Form.Show()了。我知道作用域的问题,我只是小心地绕过它们,主要是将所有东西设置为私有的,并且除非我绝对确定想要使用Form.myVariable,否则不使用它。谢谢。 - Keith
2
@Keith,这里有另一个更长的解释,涉及到默认实例的一些问题。 - Ňɏssa Pøngjǣrdenlarp

5

在表单中,VB会在幕后为您创建一个默认实例。 例如,以下VB代码:

Public Class bill_staff
    Inherits System.Windows.Forms.Form
End Class

class testclass
    sub testmethod()
        bill_staff.Show()
    end sub
end class

等同于以下C#代码:

public class bill_staff : System.Windows.Forms.Form
{

    private static bill_staff _DefaultInstance;
    public static bill_staff DefaultInstance
    {
        get
        {
            if (_DefaultInstance == null)
                _DefaultInstance = new bill_staff();

            return _DefaultInstance;
        }
    }
}

internal class testclass
{
    public void testmethod()
    {
        bill_staff.DefaultInstance.Show();
    }
}

这只会在VB窗体中(继承自System.Windows.Forms.Form的类)出现。 个人认为,这是VB中一个可怕的“特性” - 它混淆了类和实例之间的区别。


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