Почему в VB.Net есть экземпляр по умолчанию, но не на С#?
Мне просто интересно узнать, что есть свойство (Name), которое представляет собой имя класса Form. Это свойство используется в пространстве имен, чтобы однозначно идентифицировать класс, являющийся экземпляром формы, и, в случае с Visual Basic, используется для доступа к экземпляру по умолчанию формы.
Теперь, откуда этот экземпляр по умолчанию, почему С# не имеет эквивалентного метода для этого.
Также, например, чтобы показать форму на С#, мы делаем что-то вроде этого:
// 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. Но мы также знаем, что Form1
- это класс, определенный в Designer
, так как имена могут быть одинаковыми для имени экземпляра и класса?
Если Form1
- класс, то нет (Static\Shared) метода с именем Show().
Итак, откуда этот метод?
-
Какая разница в сгенерированном ИЛ?
-
И, наконец, почему С# не имеет эквивалента?
Ответы
Ответ 1
Это было добавлено обратно к языку версии VB.NET, которая поставляется с VS2005. По многочисленным просьбам программистам VB6 было трудно найти разницу между типом и ссылкой на объект этого типа. Form1 vs frm в вашем фрагменте. Там история для этого, VB не получил классов, пока VB4 пока формы не вернутся к VB1. Это в противном случае довольно вредно для программиста, понимая, что разница очень важна, чтобы получить возможность писать эффективный объектно-ориентированный код. Большая часть причин, по которым С# не имеет этого.
Вы также можете вернуть это на С#, хотя это будет не так чисто, потому что С# не позволяет добавлять свойства и методы в глобальное пространство имен, например, 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 в своем коде, так же как вы можете использовать Form2 в VB.NET. Код в выражении if getter свойства должен быть перемещен в свой собственный частный метод, чтобы сделать его эффективным, я оставил его таким образом для ясности.
Кстати, атрибут [ThreadStatic] в этом фрагменте - это то, что заставило многих программистов VB.NET отказаться от потоковой обработки в полном отчаянии. Проблема, когда абстракция протекает. Вам действительно лучше не делать этого вообще.
Ответ 2
VB добавляет нагрузку кода в ваш проект за вашей спиной, в основном.
Самый простой способ увидеть, что происходит, - создать минимальный проект и посмотреть на него с помощью Reflector. Я только что создал новое приложение WinForms с VB и добавил этот класс:
Public Class OtherClass
Public Sub Foo()
Form1.Show()
End Sub
End Class
Скомпилированный код для Foo выглядит так, когда декомпилируется как С#:
public void Foo()
{
MyProject.Forms.Form1.Show();
}
MyProject.Forms
является свойством в сгенерированном классе MyProject
типа MyForms
. Когда вы начинаете погружаться в это, вы видите там довольно большое количество сгенерированного кода.
С# мог бы все это сделать, конечно, но, как правило, у него не так много истории за спиной. Он создает дополнительные методы и типы для таких вещей, как анонимные типы, блоки итераторов, лямбда-выражения и т.д., Но не совсем так, как это делает VB. Весь код, который строит С#, соответствует исходному коду, который вы написали, - просто искусно преобразован.
Есть аргументы для обоих подходов, конечно. Лично я предпочитаю подход С#, но это, вероятно, не удивительно. Я не понимаю, почему должен быть способ доступа к экземпляру формы, как если бы он был одним, но только для форм... Мне нравится, что язык работает одинаково, независимо от того, использую ли я классы GUI или что-то еще, в основном.