Может ли кто-нибудь объяснить следующее поведение?
В целом, если вы создадите несколько библиотек, совместимых с CLS, в Visual Studio 2008 и включите их в общий корень пространства имен, библиотека, ссылающаяся на другую библиотеку, потребует ссылки на эти ссылки библиотек, даже если она не использует их.
Это довольно сложно объяснить в одном предложении, но вот шаги для воспроизведения поведения (обратите пристальное внимание на пространства имен):
Создайте библиотеку LibraryA и добавьте в нее один класс:
namespace Ploeh
{
public abstract class Class1InLibraryA
{
}
}
Убедитесь, что библиотека соответствует требованиям CLS, добавив [assembly: CLSCompliant(true)]
в AssemblyInfo.cs.
Создайте еще одну библиотеку LibraryB и Reference LibraryA. Добавьте в библиотеку следующие классы:
namespace Ploeh.Samples
{
public class Class1InLibraryB : Class1InLibraryA
{
}
}
и
namespace Ploeh.Samples
{
public abstract class Class2InLibraryB
{
}
}
Убедитесь, что LibraryB также совместим с CLS.
Обратите внимание, что Class1InLibraryB происходит от типа в LibraryA, тогда как Class2InLibraryB этого не делает.
Теперь создайте третью библиотеку с именем LibraryC и ссылкой LibraryB (но не LibraryA). Добавьте следующий класс:
namespace Ploeh.Samples.LibraryC
{
public class Class1InLibraryC : Class2InLibraryB
{
}
}
Это должно все еще компилироваться. Обратите внимание, что Class1InLibraryC происходит от класса в LibraryB, который не использует какие-либо типы из LibraryA.
Также обратите внимание, что Class1InLibraryC определяется в пространстве имен, которое является частью иерархии пространства имен, определенной в LibraryB.
До сих пор LibraryC не ссылался на LibraryA, и поскольку он не использует никаких типов из LibraryA, компиляция решений.
Теперь совместим с LibraryC CLS. Внезапно решение больше не компилируется, и вы получите сообщение об ошибке:
Тип "Ploeh.Class1InLibraryA" определен в сборке, на которую не ссылаются. Вы должны добавить ссылку на сборку 'Ploeh, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null'.
Вы можете снова скомпилировать решение одним из следующих способов:
- Удалить CLS Compliance из LibraryC
- Добавьте ссылку на LibraryA (хотя вам это не нужно)
- Измените пространство имен в LibraryC так, чтобы оно не было частью иерархии пространства имен LibraryB (например, Fnaah.Samples.LibraryC)
- Измените пространство имен Class1InLibraryB (то есть, которое не используется из LibracyC), чтобы оно не лежало в иерархии пространства имен LibraryC (например, Ploeh.Samples.LibraryB)
Кажется, что существует некоторая странная взаимосвязь между иерархией пространства имен и соблюдением CLS.
Решение этой проблемы может быть выполнено путем выбора одного из вариантов в приведенном выше списке, но может ли кто-нибудь объяснить причину такого поведения?