Как указать одно из нескольких пространств имен с точечной записью, которые неоднозначны


редактирует...

Обратите внимание: я изменяю свои фальшивые ссылки на папки, чтобы они более точно отображали, что это не папки, а пространства имен. Некоторые из комментариев здесь были до этого изменения


Я совсем новичок в C#, поэтому простите меня, если я скажу что-то не так.

Я работаю в большом решении, в котором много проектов.

Меня попросили переместить определенный класс, определенный в пространстве имен, из одного из этих проектов в другой. Однако проблема, когда я делаю это, заключается в том, что есть одно определение объекта, на которое больше не ссылаются должным образом. Вот пример:

Первоначальная структура:

Этот файл:

Main\Second.Level.Data\Second.Level.Data.csproj:

Первоначально в нем была эта строка кода:

<Compile Include = "Some\Nested\File\Way\Down.cs" />

Кроме того, здесь упоминался фактический файл:

Main\Second.Level.Data\Some\Nested\File\Way\Down.cs

Новая структура:

Сначала мы удалили строку Compile из 'Main\Second.Level.Data\Second.Level.Data.csproj и добавили аналогичную строку кода в новое пространство имен, которая выглядела так:

File: Main\Main.DataAccess\Main.DataAccess.csproj

Добавлена ​​новая строка кода:

<Compile Include = "New\Location\of\Down.cs" />

И мы переместили фактический файл в новое место, которое сейчас:

Main\Main.DataAccess\New\Location\of\Down.cs

Когда это сделано, кажется, что все ссылки (т. е. все операторы использования) работают, кроме одной. Есть один оператор using, который выглядит так:

using Main.Second.Level.Data.Yet.Another.Nested.File.Objects

В старом пространстве имен этот оператор using работал нормально, а в новом — нет. В частности, он терпит неудачу на третьем элементе (уровень). Моя IDE выдает ошибку «Не удается разрешить символ «Уровень»».

Я очень подозреваю, что причина этого заключается в том, что на самом деле существует другое пространство имен, которое называется просто «Main.Second», внутри которого есть собственный файл Main.Second.csproj. Я ни для чего не использую эту папку или файлы в ней, однако я не могу понять, как система может узнать разницу между:

using Main.Second.Level.Data.Yet.Another.Nested.File.Objects

и

using Main.Second.Some.Other.Unrelated.Stuff

Другими словами, я не понимаю, как точечная запись может указать, где начинается или заканчивается имя пространства имен.

Приложение №1:

Я определил, что проблема в том, что в файле csproj целевого проекта нет ссылки на новый проект (или, по крайней мере, я совершенно уверен, что это так). Чтобы решить эту проблему, я попытался вручную добавить эту ссылку. Обратите внимание: я использую JetBrains Rider IDE и пробовал несколько автоматических методов добавления ссылки, но ни один из них не сработал.

Чтобы добавить ссылку, я нашел блок ItemGroup со всеми другими ссылками на проект и добавил новый блок. Это выглядит так:

<ItemGroup>
  <ProjectReference Include "..\Other.Project\Other.Project.csproj">
    <Project>{fh9w8es3-nota-real-guid-example1}</Project>
    <Name>Other.Project</Name>
  </ProjectReference>
  <ProjectReference Include "..\Main.Second.Level\Other.Project.csproj">
    <Project>{AD8234HS-NOTA-REAL-GUID-EXAMPLE2}</Project>
    <Name>Main.Second.Level</Name>
  </ProjectReference>
</ItemGroup>

Обратите внимание, что при этом мне пришлось придумать руководство для элемента Project. Я пришел к выводу (после исследования), что этот GUID будет тем, который в настоящее время существует в файле решения в корне решения, в частности, это второй GUID, показанный для этого проекта. Мой приведенный выше пример — это именно то, как я сделал свой код (в частности, в том, что GUID, скопированный из файла решения, — это все заглавные буквы, а те, что в файле csproj, — нет.

Однако это не решает мою проблему. Однако я чувствую, что очень близок к решению.

using директивы и файловая структура только условно связаны друг с другом. Вам нужно посмотреть объявление пространства имен в классе, к которому вы хотите получить доступ. Это определяет, какая using директива вам нужна.
Jon Skeet 10.01.2023 19:11

Да, мне сказали это, но это не работает. Пространство имен объекта, на который делается ссылка, не изменилось, но оно недоступно из нового местоположения. Возможно, нельзя ссылаться на объект из одного проекта в другом?

Dallas Caley 10.01.2023 19:26

Очень сложно сказать, в чем проблема. Можете ли вы каким-то образом предоставить минимальный воспроизводимый пример?

Guru Stron 10.01.2023 20:08

Ведь без какого-либо способа воспроизвести проблему мы просто не сможем помочь. Вы можете абсолютно точно ссылаться на тип из одного проекта в другом проекте, если он является общедоступным и существует ссылка (прямая или косвенная) из проекта-потребителя на проект-поставщик. Но опять же, без репродукции что-то конкретное сказать сложно.

Jon Skeet 10.01.2023 20:28

Спасибо всем, мне, вероятно, потребуется несколько дней, чтобы создать что-то подобное (и, к сожалению, я не могу опубликовать фактический код). Я обнаружил одну вещь в файле .csproj нового проекта под названием «ProjectReference», которая, кажется, указывает точный способ ссылки на внешний проект, мне нужно исследовать это дальше, я думаю.

Dallas Caley 10.01.2023 20:55
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
5
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Правильный ответ на исходный вопрос, который я поставил, заключается в том, что вам нужно добавить ProjectReference в ItemGroup, как указано в добавлении, которое я разместил по исходному вопросу.

Однако в моем конкретном случае это было невозможно, потому что это вызывало циклическую ссылку. Пример:

Проект A: имел ссылку на проект B Проект A: определил и широко использовал внутренний класс, а также использовал классы в проекте B.

Проект B: были классы, которые использовались только в проекте B.

Мое изменение попыталось добавить один из классов из проекта A в проект B, однако для этого потребовалось бы добавить обратную ссылку на проект A, что и вызвало циклическую ссылку.

Чтобы решить эту проблему, я сделал следующее:

  1. Определил интерфейс в проекте B, который будет работать для моего нового класса, определенного в проекте A.

  2. Сделайте класс Project A расширением этого интерфейса

  3. Измените ссылки на класс проекта A, которые были в проекте B, чтобы ссылаться на интерфейс вместо определенного класса. Это устранило необходимость в обратной ссылке.

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

Другие вопросы по теме