为什么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()
-
我的问题来自这第一种方法。 什么是
Form1
,它是Form1
的实例还是Form1
类本身? 现在,如上所述,表单名称是VB.Net中的Default实例。 但是我们也知道Form1
是一个在Designer
定义的类,所以实例和类名的名字是如何相同的呢? 如果Form1
是一个类,则不存在名为Show()的(Static \ Shared)方法。 那么这个方法从哪里来? -
他们在生成的IL中有什么不同?
-
最后,为什么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类还是其他,基本上。