C# 在多个程序集中使用相同的完全限定类名

C# 在多个程序集中使用相同的完全限定类名,c#,clr,assemblies,C#,Clr,Assemblies,当我们在两个不同的程序集中定义相同的命名空间和类名时,.NET编译器(然后是运行时的CLR)如何确定要使用哪个类,而不使用外部别名来帮助它决定?考虑这个示例-所有在一个.cs文件中: using System; namespace Nonsense { class Program { static void Main(string[] args) { String s = new System.String();

当我们在两个不同的程序集中定义相同的命名空间和类名时,.NET编译器(然后是运行时的CLR)如何确定要使用哪个类,而不使用外部别名来帮助它决定?考虑这个示例-所有在一个.cs文件中:

using System;

namespace Nonsense
{
    class Program
    {
        static void Main(string[] args)
        {
            String s = new System.String();
        }
    }
}

namespace System
{
    public class String
    {
        // Nothing here
    }
}
这段代码编译时没有任何错误。在运行时,此代码使用上面显示的空System.String,而不是框架中的System.String。为什么?这是确定性的吗?如果是,规则是什么?将上面System.String的空实现移动到另一个程序集中并引用它会做同样的事情-Main会看到空的实现。为什么?它如何选择在自定义程序集中使用空程序集,而在框架的系统程序集中使用“真实”程序集?

您是否检查了警告? 我有以下警告:

警告CS1685:预定义类型
System.String'已定义多次。使用mscorlib.dll(CS1685)中的定义

警告CS0436:类型“System.String”与导入的同名类型冲突。忽略导入的类型定义(CS0436)


关于第一个问题的详细信息就是答案:

它与您的
使用指令有关。它们的放置位置会影响参照的解析方式。如果
using
指令放置在
命名空间
声明之外,则该命名空间的内容将加载到全局命名空间中。但是,如果
using
指令放在
命名空间
声明中,则其内容将加载到该命名空间中

最后搜索全局命名空间

您可以通过使用全局命名空间别名(如中所述)在某种程度上控制这一点

另见


在运行时,此代码使用上面显示的空System.String,而不是框架中的System.String。为什么?
——可能是因为它与名称空间声明位于同一程序集中,并且它在外部程序集中隐藏该名称空间声明。我认为编译器总是首先使用本地类型,因为您在同一程序集中命名一个类字符串。因此,在同一个程序集中命名的类将优先于外部程序集。
将上面System.String的空实现移动到另一个程序集中并引用它会做同样的事情
-这样做时,我似乎遇到了编译时错误。这对你来说确实有效吗?你说得对,彼得利兹,至少在Visual Studio 2013的框架4.5上是这样-我编辑了这个问题。@J.Davidson-如果这是答案,那就太好了。但我们怎么知道这就是答案,一直如此,每次如此?这是在C#规范的某个地方还是其他官方文件中?