Почему существует экземпляр по умолчанию для каждой формы в VB.Net, но не в C #? - PullRequest
43 голосов
/ 15 января 2011

Мне просто любопытно узнать, что есть свойство (Name), которое представляет имя класса 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()
  1. Мой вопрос возникает из-за этого первого метода.Что это за Form1, это экземпляр Form1 или сам класс Form1?Теперь, как я упоминал выше, имя формы является экземпляром по умолчанию в VB.Net.Но мы также знаем, что Form1 - это класс, определенный в Designer, так как же имена могут быть одинаковыми как для экземпляра, так и для имени класса?Если Form1 является классом, тогда нет метода (Static \ Shared) с именем Show ().Так откуда взялся этот метод?

  2. Какая разница в генерируемом IL?

  3. И, наконец, почему C # не может иметьэквивалент этого?

Ответы [ 2 ]

35 голосов
/ 15 января 2011

Это было добавлено обратно к языку в версии VB.NET, поставляемой с VS2005.По многочисленным просьбам, программистам VB6 было трудно увидеть разницу между типом и ссылкой на объект этого типа.Form1 vs frm в вашем фрагменте.Для этого есть история, VB не получал классов до VB4, в то время как формы возвращаются к 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 в своем коде, точно так же, как вы можете использовать Form2 в VB.NET.Код в операторе if свойства get должен быть перемещен в собственный закрытый метод, чтобы сделать его более эффективным, я оставил его для ясности.

Кстати, атрибут [ThreadStatic] в этом фрагменте - это то, что имеетзаставил многих программистов VB.NET отказаться от многопоточности в полном отчаянии.Проблема, когда абстракция протекает.Вы действительно лучше не делать этого вообще.

26 голосов
/ 15 января 2011

VB добавляет загрузку кода в ваш проект за спиной.

Самый простой способ увидеть, что происходит, - создать минимальный проект и посмотреть на него с помощью Reflector. Я только что создал новое приложение WinForms с VB и добавил этот класс:

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

Скомпилированный код для Foo выглядит так, когда декомпилируется как C #:

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

MyProject.Forms - это свойство в сгенерированном классе MyProject типа MyForms. Когда вы начинаете углубляться в это, вы видите довольно много сгенерированного кода там.

C # мог бы, конечно, сделать все это - но у него, как правило, не было такой истории за спиной. Он создает дополнительные методы и типы для таких вещей, как анонимные типы, блоки итераторов, лямбда-выражения и т. Д., Но не совсем так, как это делает VB. Весь код, который создает C #, соответствует написанному вами исходному коду - просто умно преобразован.

Конечно, есть аргументы для обоих подходов. Лично я предпочитаю подход C #, но это не удивительно. Я не понимаю, почему должен быть способ доступа к экземпляру формы, как если бы он был одноэлементным, но только для форм ... Мне нравится язык для работы точно так же, использую ли я классы GUI или что-то еще, в основном.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...