Запрос доступа к членству не компилируется, но статический вызов
Итак, сегодня я столкнулся с интересной проблемой, пытаясь построить наше решение для компании, и я хотел спросить вас, ребята, знаете ли вы, почему это происходит. Мне сказали, что это может быть из моей машинной/визуальной студии, потому что у других людей не было той же проблемы.
Итак, у нас есть метод в проекте 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 также установит его. Зачем? Из-за этой ситуации.
Это нормально, если я правильно понимаю ваш ответ.