Запрос доступа к членству не компилируется, но статический вызов

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

Итак, у нас есть метод в проекте A:

private static string RpcRoutingKeyNamingConvention(Type messageType, ITypeNameSerializer typeNameSerializer)
{
   string queueName = typeNameSerializer.Serialize(messageType);

   return messageType.GetAttribute<GlobalRPCRequest>() != null || AvailabilityZone == null
        ? queueName
        : queueName + "_" + AvailabilityZone;
}

где GetAttribute<GlobalRPCRequest>() определяется в public static class ReflectionHelpers

 public static TAttribute GetAttribute<TAttribute>(this Type type) where TAttribute : Attribute;

то у нас есть проект B, у которого есть метод:

public static string GetAttribute(this XElement node, string name)
{
   var xa = node.Attribute(name);
   return xa != null ? xa.Value : "";
}

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

Ошибка 966 Тип "System.Xml.Linq.XElement" определен в сборке, на которую не ссылаются. Вы должны добавить ссылку на сборку "System.Xml.Linq, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089". D:\Repositories\website\website\subsodules\core\src\A\Extensions\Extensions.cs 37 13 A

Что происходит, так это то, что компилятор думает, что я фактически использую метод GetAttribute из проекта B (на мой взгляд!). Почему это происходит? Поскольку, когда я пытаюсь перейти к GetAttribute, VS приводит меня к правильному методу (тот, который находится в ReflectionHelpers). Может быть, из-за отражения? ПРИМЕЧАНИЕ. Я исправил эту проблему, вызвав метод статически или добавив ссылку на System.Xml.Linq в моем проекте A, но мне любопытно странное поведение функции проверки VS/синтаксиса.

Ответ 1

Это догадка, но я думаю, что ваша функция:

private static string RpcRoutingKeyNamingConvention(Type messageType, ITypeNameSerializer typeNameSerializer) не соответствует вашей сигнатуре вспомогательного метода, потому что вы пытаетесь вернуть строку:

public static TAttribute GetAttribute<TAttribute>(this Type type) where TAttribute : Attribute;, который ожидает тип возврата TAttribute.

Возможно, вы можете попробовать изменить вашу функцию RpcRoutingKeyNamingConvention, чтобы вернуть GlobalRPCRequest, и проверить, продолжает ли компилятор сходить с ума.

Ответ 2

Visual Studio все время путается! Я попытался воспроизвести сценарий в VS 2015 (.NET 4.6), и он просто компилируется. Мне не нужно было добавлять ссылку на System.Xml.Linq в моем проекте A.

Я предполагаю, что это может быть проблема с кешем. Вы можете попробовать следующее:

  • Удалить ссылку на Project B
  • Очистить, затем перестроить оба решения
  • Добавить ссылку назад
  • Восстановить и вуаля!! Ну.. надеюсь.

Надеюсь, что это поможет, дайте мне знать:)

Ответ 3

Я думаю, что происходит:
- B имеет ссылку на System.Xml.Linq
- B построен без проблем.
- Вы ссылаетесь на B в
- A не получил ссылку на System.Xml.Linq
- Кажется, что потребляет функцию, определенную в B
- Когда вы пытаетесь построить проект A, он создает эту ошибку

Я прав?

Если это случай, это абсолютно нормально. Поскольку проект, который использует ссылку (A), должен иметь ссылку на то, на что ссылается (System.Xml.Linq) на то, на что он ссылается (B).

Подумайте так: когда вы пытаетесь добавить пакет nuget в свой проект, если он имеет зависимость, nuget также установит его. Зачем? Из-за этой ситуации.

Это нормально, если я правильно понимаю ваш ответ.