Подтвердить что ты не робот

Почему в 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(). Итак, откуда этот метод?

  • Какая разница в сгенерированном ИЛ?

  • И, наконец, почему С# не имеет эквивалента?

4b9b3361

Ответ 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 или что-то еще, в основном.