我正在维护一个同时具有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转换而来的 - 这是一些奇怪的遗留功能吗?
答案 0 :(得分:11)
是的,这是遗留行为。在Form1.Show
The Way 显示表单之前,类在v4之前没有出现在VB中。为了保持以前的代码兼容(VB3也非常受欢迎),保留了旧方法。
.NET仍然支持它作为显示表单的合法手段。最初,添加它是为了便于将VB6代码迁移到VB.NET。但是也可以让它很容易在VB中运行 - MS将其称为功能触手可及和类似的短语。
基本上,它为修补程序提供了一种简单的编程方式,而无需了解对象和OOP。想象一下,如果Form1.Show
犯了错误,我们将会遇到这些问题。
显式实例化是更好的方法,因为它是面向对象的,并且当您真正想要使用现有实例时,您的代码不太可能引用或创建新的Form2
。
答案 1 :(得分: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的一个可怕的“特征” - 它混淆了类和实例之间的区别。