嗯,我很清楚我的问题标题太复杂了。我只是想尽可能具体。所以,我会尝试更好地解释这个问题。
假设我们在解决方案中有三个.NET项目。主项目是一个简单的控制台应用程序 ApplicationAssembly 。此项目引用了另一个托管程序集库 DirectlyReferencedLibrary 。同时DirectlyReferencedLibrary引用 IndirectlyUsedLibrary 。
所以,项目用法看起来像这样: ApplicationAssembly - > DirectlyReferencedLibrary - > IndirectlyUsedLibrary
请注意,ApplicationAssembly并不直接使用任何声明为IndirectlyUsedLibrary的类型。我们还假设这些程序集中声明的所有类型都位于同一名称空间中。
此解决方案可编译并正常运行。
当我在一起时遇到以下情况时会出现问题:
以下是此类的示例。
using System;
namespace Test
{
public static class UnUsedType
{
// It's a generic extension method with a type restriction.
public static void Magic<T>(this T @this)
// It's a type restriction that uses a type from the IndirectlyUsedLibrary.
where T : ProblemType
{
Console.WriteLine("I do nothing actually.");
}
}
}
当我尝试编译这个项目时,我收到以下错误:
错误类型&#39; Test.ProblemType&#39;在未引用的程序集中定义。你必须添加一个对assembly&#39; IndirectlyUsedLibrary,Version = 1.0.0.0,Culture = neutral, 公钥=空&#39 ;. C:\ Projects \ Test \ ApplicationAssembly \ Program.cs 22 13 ApplicationAssembly
任何人都可以帮我理解为什么会这样吗?
我做了一个很小的调查解决方案。 如果您非常友好地帮助我,您将可以 an archived solution here
抱歉我的英语不好。
另一个奇怪的事情是LINQ方法的不同调用可能会或可能不会产生编译时错误:
// Ok. Let's do some work using LINQ we love so much!
var strings = new[] { "aaa", "bbb", "ccc" };
Func<string, object> converter = item => (object) item;
// The following line makes problems.
var asObjects1 = strings.Select(converter);
// Everything is OK if we use the following line:
var asObjects2 = Enumerable.Select(strings, converter);
答案 0 :(得分:14)
任何人都可以帮我理解为什么会这样吗?
C#编译器合理地期望在引用时可以使用引用程序集的传递闭包。它没有任何类型的高级逻辑可以解释它确实需要的,可能需要的,可能不需要的,或者肯定不需要知道为了解决类型分析中的所有问题,你的程序将抛出它。如果直接或间接引用程序集,则编译器会假定其中可能存在所需的类型信息。
另外,如果在编译时没有引用程序集的集合,那么用户在运行时会有什么期望呢?期望编译时环境至少具有在运行时需要的一组程序集似乎是合理的。
我不想这样做。
我们都必须做我们生活中不想做的事情。
答案 1 :(得分:2)
我认为您知道这一点,但因为类型ProblemType
在“IndirectlyUsedLibrary”中定义,但是Magic
扩展方法的必需定义,必须引用它才能在编译时可用。
关于“为什么”......好吧,编译器需要知道它编译的细节不是吗?对我来说,编译器需要在运行时需要的最小编译时引用集合才有意义......
答案 2 :(得分:1)
如果对库使用不同的命名空间,则不会出现错误。在不同的库中使用相同的命名空间真的很奇怪。
看起来编译器在您第一次使用any时会开始扫描您的Test命名空间中的扩展名。因此需要参考。