Структура программы и ее компоненты на C#

Я не уверен корректно ли я задал вопрос,хочу узнать правильно ли я понимаю следующее.

Программа – это некая сборка, которая состоит из пространств имен, а те в свою очередь из классов. Сборка – это физический элемент, хранящийся на диске. В Visual Studio, в обозреватели решений, решения и есть сборки, а проекты этих сборок – это пространства имен? И хотелось бы узнать может ли несколько таких решений компилироваться в программу, то есть состоять из нескольких сборок.


Ответы (2 шт):

Автор решения: tym32167

Если говорить уж очень простым языком и опустить некоторые неточности, то

Сборка - это файл с кодом (классами), выглядит как имя_файла.dll.

Программа - это EXE файл (исполняемый файл) с классами (то есть с кодом), который можно запустить через проводик windows просто дважды кликнув по нему.

Разница между программой и сборкой только в том, что программу можно запустить кликнув по ней, сборку нельзя. Чтобы запустить код из сборки, нужна программа, которая на эту сборку будет ссылаться.

Простарнство имен - название говорит само за себя. Вот вы создаете класс MyClass, и какой то вася создает класс MyClass, и может ещё миллион человек создают классы с названием MyClass. И чтобы все эти классы можно было бы испольщовать вместе, придумали пространства имен. Это как имя и фамилия, где имя - это имя класса, а фамилия - простанство имен. Вы можете знать 10 Вась, но при этом различать их по фамилии. Но вот если будут 2 Васи с одинаковой фамилией, в пастпортном столе начнется путаница. Потому вы не можете в одно простанство имен засунуть 2 одинаковых класса. Простанство имен не привязано ни к сборке, ни к программе ни к проекту. Вы можете создавать сборки с любым количеством пространств имен в них, или использовать единое пространство имен для всех сборок. По сути, вы можете давать любые фамилии своим классам до тех пор, пока имя и фамилия класса уникальны в вышей программе и во всех сборках, на которые ваша программа ссылается.

В Visual Studio есть решения, решение делится на проекты. Проект может быть программой, сборкой или чем то ещё (например, есть проект баз данных).

Вы, для простоты, в своей голове можете считать, что каждый проект - это в итоге либо программа, либо сборка. Каждый проект компилируется отдельно, у каждого проекта что то своё на выходе, но проекты могут зависеть друг от друга. Например, вы можете иметь решение, где один проект-программа, и он ссылается на несколько проектов-сборок.

Чтобы объединить несколько проектов во что то одно, используется решение. Решение - это просто объединение проектов. У самого решения, как такового, на выходе нет ничего. Компиляция решения означает просто компиляцию каждого проекта, что в это решение входит.

→ Ссылка
Автор решения: return

Проект – это просто папка (вы можете через проводник залезть туда и в этом убедиться). Проект, в случае с C#, обладает 1-м св-вом – он может брать и компилировать файлы с C# кодом. Конечно, это делает не сама VS, а компилятор, но она является "мостиком" м-ду "низкоуровневым" компилятором и высокоуровневой кнопкой «Собрать»/«Запустить».

Так вот, продукт компиляции называется сборкой. Сборка – это просто контейнер типов. В C# сборка может иметь физических 2 вида (2 расширения файла) (Windows): .exe и .dll. Файлы .exe – это запускаемые (executable) приложения (applications), а файлы .dll – это переносимая (portable) библиотека (library). Библиотеки созданы для того, чтобы их включать в приложения и не переписывать код, давно уже написанный. А приложения этот код используют при своём запуске.

Так что же такое это пространство имён? Пространство имён создано с такой же целью, что и папки: их задача создать иерархию типов, для более простого восприятия, чтобы все-все типы не толпились у вас под рукой. Пространство имён – это часть имени типа. Например, у полного имени типа System.Int32 (в C# просто int) System – пространство имён, а Int32 – короткое имя типа. Ещё больше примеров:

System
├ Int32
├ Diagnostics
│ └ Process
├ Windows
│ ├ Window
│ ├ UIElement
│ └ Controls
│   └ Button
└ Collections
  └ Hashtable

Из этого понятного дерева типов в реальности формируется обычный список:

System.Int32
System.Diagnostics.Process
System.Windows.Window
System.Windows.UIElement
System.Windows.Controls.Button
System.Collections.Hashtable

Вот в таком виде (в виде списка), мы и используем типы:

System.Span<System.Byte> span = default;
ref System.Byte @ref = ref System.Runtime.InteropServices.MemoryMarshal
    .GetReference(span);

Согласитесь, читать не возможно. Для этого добавили директиву using:

using System

Теперь нам не придётся постоянно писать System.Byte, а просто Byte:

using System;
using System.Runtime.InteropServices;
⋮
Span<Byte> span = default;
ref Byte @ref = ref MemoryMarshal.GetReference(span);

Вы не должны вникать в суть кода: объём кода и его читаемость стали в разы лучше.

Но тогда вы спросите: зачем нужны пространства имён, если мы их в коде почти-что явно не используем? Всё просто: есть 2 типа:

  • System.Windows.Controls.Button – тип кнопки в WPF
  • System.Windows.Forms.Button – тип кнопки в WinForms

И то и то кнопка, но у них будет происходить конфликт, который без пространств имён разрешить нормально никак не получиться.

Есть примеры и по-реалистичнее (но думаю вы поняли саму суть):

  • System.IO.Path
  • System.Windows.Media.Path

Осталось понять, что такое решение. Это ещё проще: это просто контейнер проектов. Вот и всё. Но у него также есть 1 св-во: он позволяет ссылаться (добавлять в зависимости в .NET Core) библиотеки ваших же проектов с автокомпиляцией.

Т. е. у вас есть какое-нибудь такое решение:

MySolution
├ MyApplication (C# WPF Application)┐
└ MyLibrary (C# Class Library)←─────┘

Как мы видим, в нашем решении есть 2 проекта: WPF приложение MyApplication и библиотека классов MyLibrary. При этом, наш проект MyApplication ссылается на проект MyLibrary, что позволяет ему использовать типы из нашей библиотеки. При этом, если мы попытаемся собрать MyApplication, то автоматически будет собрана и MyLibrary, т. к. мы на неё ссылаемся. Решение объединяет проекты в первую очередь по смыслу.


Сделаем короткий review всего вышесказанного:

  • Решение – это контейнер проектов
  • Проект – это папка
  • Проекты в решении могут ссылаться друг на друга
  • Проект C# – это проект (т. е. папка) с исходным кодом C#, который может брать и компилировать этот код в сборку
  • Сборка – это контейнер типов
  • Сборка может иметь физическую интерпретацию в виде .exe и .dll файлов
  • Полное имя типа состоит из пространства имён и короткого имени типа
  • Пространства имён созданы для иерархичности и избежания конфликтов
  • Пространства имён можно послать куда по-дальше неявно использовать с помощью using и забыть о них как о страшном сне

ДОПИНг (ДОПолнительная ИНформация):

→ Ссылка