为什么VB.Net中的每个表单都有默认实例,而C#中没有?

She*_*Pro 43 c# vb.net winforms

我只是想知道有(Name)属性,它表示Form类的名称.此属性在命名空间内用于唯一标识Form是其实例的类,并且在Visual Basic的情况下,用于访问表单的默认实例.

现在,这个默认实例的来源,为什么C#不能有一个等效的方法.

另外例如,为了在C#中显示一个表单,我们执行以下操作:

// Only method
Form1 frm = new Form1();
frm.Show();
Run Code Online (Sandbox Code Playgroud)

但是在VB.Net中我们有两种方法可以做到:

' First common method
Form1.Show()

' Second method
Dim frm As New Form1()
frm.Show()
Run Code Online (Sandbox Code Playgroud)
  1. 我的问题来自第一种方法.这是什么Form1,它是一个实例 Form1Form1类本身?现在,正如我上面提到的,Form名称是VB.Net中的Default实例.但我们也知道这Form1是一个定义的类,Designer那么实例和类名的名称是如何相同的?如果Form1是一个类,则没有名为Show()的(Static\Shared)方法.那么这种方法来自哪里?

  2. 他们在生成的IL中有什么不同?

  3. 最后为什么C#不能与之相提并论呢?

Han*_*ant 36

这被添加回VS2005附带的VB.NET版本中的语言.根据大众的需求,VB6程序员很难看到类型和对该类型对象的引用之间的差异.你的代码片段中的Form1 vs frm.有这样的历史,VB直到VB4才获得类,而表单一直回到VB1.对于程序员来说,这是非常严重的,理解差异对于编写有效的面向对象代码非常重要.C#没有这个的很大一部分原因.

您也可以在C#中获得它,尽管它不会那么干净,因为C#不允许像VB.NET那样向全局命名空间添加属性和方法.您可以在表单代码中添加一些粘合剂,如下所示:

public partial class Form2 : Form {
    [ThreadStatic] private static Form2 instance;

    public Form2() {
        InitializeComponent();
        instance = this;
    }

    public static Form2 Instance {
        get {
            if (instance == null) {
                instance = new Form2();
                instance.FormClosed += delegate { instance = null; };
            }
            return instance;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

您现在可以在代码中使用Form2.Instance,就像您可以在VB.NET中使用Form2一样.应该将属性getter的if语句中的代码移动到它自己的私有方法中以使其有效,为了清楚起见,我这样做了.

顺便说一句,该片段中的[ThreadStatic]属性使许多VB.NET程序员完全绝望地放弃了线程.抽象漏洞时的问题.你是真的关闭不这样做要好.

  • @ThomasLevesque:*'太愚蠢了解OOP'*?不,我建议你停止这种想法.Hans Passant的回答表明在VB4之前VB中不存在类,因此需要将这个特性放在VB.NET中以简化从VBX到VB.NET的项目升级.如果你已经尝试将任何非平凡的VBX应用程序升级到VB.NET,你就会知道你可能会得到多少错误,并且你会欣赏任何可以减少开发人员工作量的"非标准"语言调整.是的,MarkJ是对的,它不应该用在新的代码中,但VB开发人员绝对不是愚蠢的,否则他们不会出现. (13认同)
  • 将其添加到VB.Net的一个重要原因是帮助将现有代码从VB1-3移植到VB.Net,其中该功能将被使用,因为没有替代方案.这就是为什么我很高兴它被添加:个人我不认为它应该在新代码中使用.尽管我支持这个功能和VB6的一些经验,但我认为我个人在理解类型和类型实例的引用之间的区别时没有任何问题:) (3认同)
  • 所以基本上VB.NET语言被修改了,因为用户太愚蠢而无法理解OOP ......我总是惊讶于这种语言在很多方面都存在缺陷,同时仍然具有与C#几乎相同的功能. (2认同)
  • 以更高理想的名义犯下了可怕的罪行。例如,“选项严格关闭” (2认同)

Jon*_*eet 26

VB基本上是在你背后的项目中添加一堆代码.

查看正在发生的事情的最简单方法是构建一个最小的项目并使用Reflector查看它.我刚刚用VB创建了一个新的WinForms应用程序并添加了这个类:

Public Class OtherClass    
    Public Sub Foo()
        Form1.Show()
    End Sub
End Class
Run Code Online (Sandbox Code Playgroud)

当反编译为C#时,Foo的编译代码如下所示:

public void Foo()
{
    MyProject.Forms.Form1.Show();
}
Run Code Online (Sandbox Code Playgroud)

MyProject.Forms是生成的MyProject类中的属性,类型MyForms.当你开始深入研究时,你会看到相当多的生成代码.

当然,C#可以完成所有这些工作 - 但它通常不具备在你背后做得多的历史.它为诸如匿名类型,迭代器块,lambda表达式等之类的东西构建额外的方法和类型 - 但不像VB在这里做的那样.C#构建的所有代码都对应于您编写的源代码 - 只是巧妙地转换.

当然,这两种方法都存在争议.我个人更喜欢C#方法,但这可能并不奇怪.我不明白为什么应该有一种方法来访问一个表单的实例,就像它是一个单例而只是表单...我喜欢这种语言以相同的方式工作,无论我是使用GUI类还是其他任何东西,基本上.

  • @Javed:那么大概是你不是从不同的班级使用它,就像我在我的例子中一样. (4认同)