C # — Как компилятор находит другую часть частичного класса?

#c#

#c#

Вопрос:

Я использую VS2010 SP1.

После создания демонстрационного проекта для приложения C # Form структура моего решения содержит следующую информацию

 Form1.cs
   Form1.Designer.cs
   Form1.resx

// File Form1.cs
namespace WinFormApp
{
  public partial class Form1 : Form
  {
    public Form1()
    {
      InitializeComponent();
    }
  }
}

// File Form1.Designer.cs
namespace WinFormApp
{
  partial class Form1
  {

    private void InitializeComponent()
    {
      ...
    }
    ...
   }
}
  

Вот в чем вопрос,
Я вижу, что Form1 является частичным классом. Однако, как компилятор узнает, где найти другую его часть? * Другими словами, существует ли привязка между файлом Form1.cs и Form1.Designer.cs?* Здесь, как вы можете видеть, другая часть определена внутри Form1.Designer.cs. Я предполагаю, что там есть подсказки, чтобы компилятор мог быстро найти весь код реализации для частичного класса. Пожалуйста, поправьте меня.

Спасибо

Комментарии:

1. он находит его так же, как находит весь код, благодаря тому, что он находится в вашем проекте

2. @David, я изначально думал, что там могут быть подсказки, такие как включить файлы на C , чтобы ускорить поиск :). Как я знал, в C # нет файлов, включающих файлы, за исключением частичных методов.

Ответ №1:

Компилятор C # — это компилятор с двумя проходами. Система проекта предоставляет компилятору список всех файлов в проекте. Компилятор сначала выполняет сканирование «верхнего уровня» всех файлов и создает таблицу, из которой файлы содержат какие пространства имен, типы, методы, свойства, события, поля и так далее, Но он не просматривает тела методов.

Когда эта таблица будет создана, мы сможем использовать ее для проверки всей программы на «верхнем уровне». В это время мы выясняем, какие частичные объявления действительно являются «одним и тем же классом». На этом этапе мы устраняем частичность, мы разрешаем базовые типы и ограничения на универсальные параметры, мы удостоверяемся, что все методы «переопределения» фактически переопределяют соответствующий виртуальный метод и так далее.

Как только анализ «верхнего уровня» выполнен, только тогда мы анализируем тела методов.

Имена файлов не имеют значения; компилятор использует их только для сообщения об ошибках. Совершенно законно иметь дюжину классов и сотню файлов и частичное объявление каждого класса в каждом файле. (Хотя, пожалуйста, на самом деле не делайте этого; это значительно увеличивает нагрузку на IDE, когда люди делают подобные вещи, потому что нам становится трудно быстро определить, что представляют собой все члены класса, пока вы вводите изменения!)

Комментарии:

1. приятно знать, что ты парень с MS 🙂 Неудивительно, что это официальный ответ! — большое спасибо

2. Ваше примечание в скобках объясняет медлительность нашей IDE, возникшую при работе с нашим массивным классом DataRepository, разделенным на десятки частичных классов…

3. @Джеймс: Ну, это могло бы это объяснить. У нас была ошибка в IDE много лет назад, когда мы были крайне неоптимальны в сценарии, где нам приходилось проверять десятки частичных классов, чтобы увидеть, содержат ли они какие-либо методы расширения, где каждый частичный класс был разбросан по сотням файлов. Мы исправили эту проблему, но если вы испытываете действительно сильную медлительность, там может быть какая-то другая проблема, о которой мы должны знать. Если вы еще этого не сделали, рассмотрите возможность ввода отчета о connect.microsoft.com и команда тестирования IDE посмотрит на это.

4. Кстати, поздравляю с достижением 100 тыс. Извините, я пропустил это, но технически я этого не сделал, потому что фактическое число все еще меньше 101, сайт просто округляет его: O Спасибо, что меняете жизни людей к лучшему. Сообщество SO и / или сайт должны преподнести вам серьезный подарок, возможно, в виде мощного компьютера, которым вы можете наслаждаться.

Ответ №2:

Все файлы отправляются компилятору, здесь нет никакой магии.

Ответ №3:

Нет никаких требований в отношении имен файлов. Вы могли бы иметь Foo.cs и Bar.cs . (И каждый из них может содержать несколько разных частичных классов.) Компилятору предоставляются все файлы для компиляции для конкретной сборки за один раз — и он просматривает только эти файлы. Он не просматривает файловую систему в поисках других исходных файлов или чего-то подобного.

Ответ №4:

Когда компилятор C # получает все файлы, он сканирует все файлы.Если он находит классы с одинаковым именем и частичным модификатором, то он распознает их как один и тот же класс, собирает их и компилирует.