简体   繁体   English

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

[英]Why is there a default instance of every form in VB.Net but not in C#?

I'm just curious to know that there is the (Name) property, which represents the name of the Form class.我只是想知道有 (Name) 属性,它表示 Form 类的名称。 This property is used within the namespace to uniquely identify the class that the Form is an instance of and, in the case of Visual Basic, is used to access the default instance of the form.此属性在命名空间中用于唯一标识 Form 是其实例的类,并且在 Visual Basic 的情况下,用于访问窗体的默认实例。

Now where this Default Instance come from, why can't C# have a equivalent method to this.现在这个默认实例来自哪里,为什么 C# 不能有一个等效的方法呢。

Also for example to show a form in C# we do something like this:例如,要在 C# 中显示表单,我们会执行以下操作:

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

But in VB.Net we have both ways to do it:但是在 VB.Net 中,我们有两种方法可以做到:

' First common method
Form1.Show()

' Second method
Dim frm As New Form1()
frm.Show()
  1. My question comes from this first method.我的问题来自第一种方法。 What is this Form1 , is it an instance of Form1 or the Form1 class itself?这是什么Form1 ,它是一个实例Form1Form1类本身? Now as I mentioned above the Form name is the Default instance in VB.Net.现在正如我上面提到的,表单名称是 VB.Net 中的默认实例。 But we also know that Form1 is a class defined in Designer so how can the names be same for both the Instance and class name?但是我们也知道Form1是在Designer定义的一个类,那么实例名和类名的名称如何相同呢? If Form1 is a class then there is no (Static\\Shared) method named Show().如果Form1是一个类,则没有名为 Show() 的 (Static\\Shared) 方法。 So where does this method come from?那么这个方法从何而来呢?

  2. What difference they have in the generated IL?它们在生成的 IL 中有什么区别?

  3. And finally why can't C# have an equivalent of this?最后,为什么 C# 不能有这样的等价物?

This was added back to the language in the version of VB.NET that came with VS2005.这被添加回 VS2005 附带的 VB.NET 版本中的语言。 By popular demand, VB6 programmers had a hard time with seeing the difference between a type and a reference to an object of that type.应大众的要求,VB6 程序员很难看出类型和对该类型对象的引用之间的区别。 Form1 vs frm in your snippet.您的代码段中的 Form1 与 frm。 There's history for that, VB didn't get classes until VB4 while forms go all the way back to VB1.这是有历史的,VB 直到 VB4 才获得类,而表单一直回到 VB1。 This is otherwise quite crippling to the programmer's mind, understanding that difference is very important to get a shot at writing effective object oriented code.否则这对程序员来说是相当严重的,理解差异对于编写有效的面向对象代码非常重要。 A big part of the reason that C# doesn't have this. C# 没有这个的很大一部分原因。

You can get this back in C# as well, albeit that it won't be quite so clean because C# doesn't allow adding properties and methods to the global namespace like VB.NET does.您也可以在 C# 中恢复它,尽管它不会那么干净,因为 C# 不允许像 VB.NET 那样向全局命名空间添加属性和方法。 You can add a bit of glue to your form code, like this:您可以在表单代码中添加一些胶水,如下所示:

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;
        }
    }
}

You can now use Form2.Instance in your code, just like you could use Form2 in VB.NET.您现在可以在代码中使用 Form2.Instance,就像您可以在 VB.NET 中使用 Form2 一样。 The code in the if statement of the property getter should be moved into its own private method to make it efficient, I left it this way for clarity.属性 getter 的 if 语句中的代码应该移动到它自己的私有方法中以使其高效,为了清晰起见,我保留了这种方式。

Incidentally, the [ThreadStatic] attribute in that snippet is what has made many VB.NET programmers give up threading in utter despair.顺便说一句,该代码段中的 [ThreadStatic] 属性使许多 VB.NET 程序员在极度绝望中放弃了线程。 A problem when the abstraction is leaky.抽象泄漏时的问题。 You are really better off not doing this at all.真是最好在所有不这样做。

VB is adding a load of code into your project behind your back, basically.基本上,VB 正在背后向您的项目中添加大量代码。

The easiest way to see what's going on is to build a minimal project and look at it with Reflector.查看正在发生的事情的最简单方法是构建一个最小的项目并使用 Reflector 查看它。 I've just created a new WinForms app with VB and added this class:我刚刚用 VB 创建了一个新的 WinForms 应用程序并添加了这个类:

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

The compiled code for Foo looks like this when decompiled as C#: Foo 的编译代码在反编译为 C# 时如下所示:

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

MyProject.Forms is a property in the generated MyProject class, of type MyForms . MyProject.Forms是生成的MyProject类中的一个属性,属于MyForms类型。 When you start diving into this you see quite large amounts of generated code in there.当您开始深入研究时,您会在其中看到大量生成的代码。

C# could do all of this, of course - but it doesn't typically have a history of doing quite as much behind your back.当然,C#可以完成所有这些 - 但它通常没有在你背后做那么多事情的历史。 It builds extra methods and types for things like anonymous types, iterator blocks, lambda expressions etc - but not in quite the same way that VB does here.它为匿名类型、迭代器块、lambda 表达式等构建了额外的方法和类型——但与 VB 在这里所做的方式不同。 All the code that C# builds corresponds to source code that you've written - just cleverly transformed. C# 构建的所有代码都对应于您编写的源代码 - 只是巧妙地进行了转换。

There are arguments for both approaches, of course.当然,这两种方法都有论据。 Personally I prefer the C# approach, but that's probably no surprise.我个人更喜欢 C# 方法,但这可能不足为奇。 I don't see why there should be a way of accessing an instance of a form as if it was a singleton but only for forms... I like the language to work the same way whether I'm using GUI classes or anything else, basically.我不明白为什么应该有一种访问表单实例的方法,就好像它是单例一样,但适用于表单......无论我使用 GUI 类还是其他任何东西,我都喜欢这种语言以相同的方式工作, 基本上。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM