简体   繁体   English

C#隐藏参考

[英]C# Hidden References

I am trying to determine which dlls my assemblies need to compile. 我试图确定我的程序集需要编译哪些dll。 I have two sample projects, Scratch and ScratchTest both in one solution. 我在一个解决方案中有两个示例项目Scratch和ScratchTest。 Here is Scratch's Program.cs: 这是Scratch的Program.cs:

using System.ServiceProcess;

namespace Scratch
{
    public class A : ServiceBase
    {
        static void Main(string[] args)
        {
        }
    }
}

Scratch has a reference to System.ServiceProcess.dll. Scratch引用了System.ServiceProcess.dll。

Here is ScratchTest's program.cs: 这是ScratchTest的program.cs:

namespace ScratchTest
{
    class Program
    {
        static void Main(string[] args)
        {
        Scratch.A o;
        }
    }
}

ScratchTest has to reference BOTH Scratch and System.ServiceProcess.dll. ScratchTest必须同时引用Scratch和System.ServiceProcess.dll。 However, the resulting ScratchTest.dll has no reference to System.ServiceProcess.dll, only Scratch. 但是,生成的ScratchTest.dll没有引用System.ServiceProcess.dll,只有Scratch。 I know this both by looking at 我都知道这两个

Assembly.GetReferencedAssemblies()

and by using .net reflector. 并使用.net反射器。 So my question is, how can I tell that ScratchTest requires System.ServiceProcess.dll to compile? 所以我的问题是,我怎么能说ScratchTest需要System.ServiceProcess.dll进行编译? Especially considering SratchTest wouldn't necessarily want to reference all of Scratch's references because there might be some conflicting ones. 特别是考虑到SratchTest不一定要引用所有Scratch的引用,因为可能会有一些冲突。 Thanks, Eric 谢谢,埃里克

First thing is that the problem that you are facing is not specific to ServiceBase Class. 第一件事是您面临的问题并非特定于ServiceBase类。 It is pertaining to how exactly CLR detects the type dependencies for a C# program and loads the referenced assemblies. 它与CLR如何准确地检测C#程序的类型相关性并加载引用的程序集有关。 C# compiler is simply giving you an error in advance at compile time itself as the same will fail at run time also when CLR tries to run your program. C#编译器只是在编译时预先给您一个错误,因为当CLR尝试运行您的程序时,该错误也会在运行时失败。 Here is what I'm assuming while explaining the solution to your problem: 这是我在解释您的问题的解决方案时所假定的:

ScratchTest is your start-up project although you have defined two entry points in your solution as Main method is present in both "Scratch" and "ScratchTest" projects. 尽管您已经在解决方案中定义了两个入口点,但ScratchTest是您的启动项目,因为Main方法同时存在于“ Scratch”和“ ScratchTest”项目中。 To avoid confusion generally you should have only one main method (entry point) for your solution though it has no impact on your current problem. 为了避免混淆,尽管您的解决方案不会对您当前的问题产生任何影响,但通常只应为您的解决方案提供一种主要方法(入口点)。

Solution : When you refer class A in scratchTest project you are not referring only to class A but the class ServiceBase as well because class "A" is inheriting from it. 解决方案 :当您在scratchTest项目中引用类A时,您不仅在引用类A,而且还引用了ServiceBase类,因为类“ A”是继承自它。 So when compiler tries to compile your ScratchTest Project it tries to find the dependency types namely "A" and ServiceBase both in the assemblies that are currently referenced. 因此,当编译器尝试编译您的ScratchTest项目时,它将尝试在当前引用的程序集中找到依赖类型,即“ A”和ServiceBase The point of importance here is that CLR always tries to find the dependency types only in the assemblies whose reference is present directly in the manifest meta-data of the assembly itself which you are trying to load (which is ScratchTest in this case). 这里的重点是,CLR始终尝试仅在其引用直接存在于您要加载的程序集本身的清单元数据中的程序集中查找依赖项类型(在本例中为ScratchTest)。 Dependency types are NEVER searched in a recursive fashion the way you have structured your solution. 从不以构造解决方案的方式递归搜索依赖类型。 Essentially expecting CLR to search a dependency type in all the referenced assemblies and in turn their referenced assemblies will be hell lot of performance impact at start-up of your .Net application. 本质上期望CLR在所有引用的程序集中搜索依赖项类型,然后依次引用它们的引用程序集,这将对.Net应用程序启动产生很大的性能影响。

At the same time the core .Net libraries like MsCorLib , System , System.Core , System.Data are usually referenced in most of the C# projects you create. 同时,您创建的大多数C#项目中通常都引用MsCorLibSystemSystem.CoreSystem.Data类的核心.Net库。 Then considering the case otherwise had CLR implemented the logic of recursively finding the dependency types through referenced assemblies then it would have been making an extra effort by making a check every time whether it had already gone past a specific assembly or not while searching a dependency type which would have hurt start-up performance further. 然后考虑其他情况,如果CLR实施了通过引用程序集递归查找依赖项类型的逻辑,那么它将在每次搜索依赖项类型时检查是否已经通过特定程序集进行检查,从而付出了额外的努力。这会进一步损害启动性能。

To fix your code you can do following two things : 要修复您的代码,您可以执行以下两项操作:

  • Add reference to System.ServiceProcess.dll to ScratchTest project as advised by the C# compiler. 根据C#编译器的建议,将对System.ServiceProcess.dll引用添加到ScratchTest项目。

OR 要么

  • Use the class A in "ScratchTest" project itself as it already contains a reference to System.ServiceProcess.dll 在“ ScratchTest”项目本身中使用类A,因为它已经包含对System.ServiceProcess.dll的引用

I don't think you need to explicit call System.ServiceProcess on the test file. 我认为您不需要在测试文件上显式调用System.ServiceProcess。

The Test file is not using any reference to any method or class inside System.ServiceProcess, just using Scratch. 测试文件没有使用对System.ServiceProcess中任何方法或类的任何引用,仅使用了Scratch。

You do not need to requieres all the libraries that the referenced clases uses, just the one are currently used by your class. 您无需要求引用的分类库使用的所有库,只需类当前正在使用的库即可。

So ScratchTest is only using Scrath and Scratch is using System.ServiceProcess. 因此,ScratchTest仅使用Scrath,而Scratch使用System.ServiceProcess。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM