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

我只是好奇,知道有(名称)属性,它代表了表单类的名称。 此属性在名称空间内用于唯一标识Form是实例的类,在Visual Basic的情况下,用于访问表单的默认实例。

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

也例如在C#中显示一个表单,我们做这样的事情:

// Only method Form1 frm = new Form1(); frm.Show(); 

但在VB.Net中,我们有两种方法来做到这一点:

 ' First common method Form1.Show() ' Second method Dim frm As New Form1() frm.Show() 
  1. 我的问题来自这第一种方法。 什么是Form1 ,它是Form1的实例还是Form1类本身? 现在,如上所述,表单名称是VB.Net中的Default实例。 但是我们也知道Form1是一个在Designer定义的类,所以实例和类名的名字是如何相同的呢? 如果Form1是一个类,则不存在名为Show()的(Static \ Shared)方法。 那么这个方法从哪里来?

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

  3. 最后,为什么C#没有这个相同的function呢?

这被添加到VS2005附带的VB.NET版本中。 根据大众的需求,VB6程序员很难看出这种types的对象的types和引用之间的区别。 Form1 vs frm在你的片段。 有这样的历史,VB直到VB4,而forms一直回到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; } } } 

您现在可以在代码中使用Form2.Instance,就像在VB.NET中使用Form2一样。 属性getter的if语句中的代码应该被移到它自己的私有方法中,以使其更高效。

顺便说一下,该代码片段中的[ThreadStatic]属性使许多VB.NET程序员放弃了绝对的绝对线程。 抽象是有漏洞的问题。 你最好不要这样做。

VB基本上是在你背后的项目中join一些代码。

最简单的方法是build立一个最小的项目,并用Reflector来查看。 我刚刚用VB创build了一个新的WinForms应用程序,并添加了这个类:

 Public Class OtherClass Public Sub Foo() Form1.Show() End Sub End Class 

Foo的编译代码看起来像这样反编译为C#时:

 public void Foo() { MyProject.Forms.Form1.Show(); } 

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

当然,C# 可以完成所有这些工作,但是它通常不会在背后做很多事情。 它为匿名types,迭代器块,lambdaexpression式等构build了额外的方法和types,但并不像VB那样。 C#构build的所有代码都与您编写的源代码相对应 – 只是巧妙地进行了转换。

当然,两种方法都有争议。 我个人更喜欢C#的方法,但这可能并不奇怪。 我不明白为什么应该有一种方法来访问一个窗体的实例,就好像它是一个单例,但适用于窗体…我喜欢语言工作方式相同,无论是使用GUI类还是其他,基本上。