我有一个包含2个项目的解决方案:
dll引用了另一个dll(b)
控制台应用程序项目仅引用了dll(a)
dll(b)有一个通用的单例类:
public class Singleton<T> where T : class
{
private static T instance;
public static T Instance
{
get
{
return instance;
}
}
static Singleton()
{
instance = (T)Activator.CreateInstance(typeof(T), true);
}
}
dll(a)有一个继承自这个类的Logger类。在控制台应用程序中,我创建了一个logger类的实例。
重建项目时,我收到此错误:
“CSUtilities.Singleton`1”类型在未引用的程序集中定义。您必须添加对程序集“CSUtilities,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null”的引用。
当我向控制台应用程序项目添加对dll(b)的引用时,问题就解决了。
我的问题是:如果我已经有dll(a)的引用,为什么我需要为dll(b)添加引用?
答案 0 :(得分:2)
在控制台应用程序中,我创建了一个logger类的实例。
正确 - 所以你要创建一个派生自Singleton<T>
的类型的实例。 (我们将设置问题放在一边,你可以创建一个单独的子类,或者显然有一个公共构造函数......)
假设你写了:
instance.SomeMethod();
如果编译器不了解Singleton<T>
,那么编译器如何知道如何解决? Singleton<T>
实际上是子类API的一部分......因此必须有对它的引用。
那是在编译时...另外,你无论如何都需要在执行时包含Singleton<T>
的DLL。如果您需要在编译时添加对不是所需的内容的引用,那么您最终会遇到更棘手的问题,因为依赖项仅用于您实际参考的图书馆的内部实施。它总是让我觉得难看,但它在其他方面很有意义,因为你肯定需要在执行时出现DLL。
答案 1 :(得分:0)
由于您在(c)中创建了一个记录器,编译器需要检查此记录器。 Logger是使用dll(b)定义的,因此编译器必须引用(b)才能编译代码callign Logger。
答案 2 :(得分:0)
我猜你的问题不是为什么对 dll B 的引用是必要的,但为什么不是 Visual Studio 自动为您添加。
这只能由 VS 团队回答,但我可以猜测它为什么会这样运作。
基本上有两个选项:在添加 dll A 作为对第三个项目的引用时自动添加 dll A 的所有引用,或者除之外不添加任何内容> dll A 参考。 VS 团队选择了后者。为什么呢?
我的猜测是因为引用 dll B 的要求取决于第三个项目的具体代码;它并不总是需要,所以不添加它是一种避免不必要地增加编译程序集的足迹的方法。另外,请记住,如果引用是必要的,它将在编译时显而易见并出现错误(您的情况)。
另一方面,如果所有引用都是自动添加的,那么在这种情况下,您不会收到任何错误或警告,表明dll B
未被使用。是的,这可以在编译时进行优化(与不必要的using
语句相同)但是为什么当另一个选项已经非常方便并且不需要额外的工作时大惊小怪呢?