`using`指令的位置在C#中有影响吗?

5
今天我在尝试对现有代码进行一些格式化时遇到了错误。原始代码的using指令是在命名空间之外声明的:
using System.Collections.Generic;
namespace MyNamespace
{
    using IntPair = KeyValuePair<int, int>;
}

当我尝试在语句中插入using指令(以符合StyleCop的规则)时,在别名指令处出现了错误,我不得不完全限定它:

namespace MyNamespace
{
    using System.Collections.Generic;
    //using IntPair = KeyValuePair<int, int>;   // Error!
    using IntPair = System.Collections.Generic.KeyValuePair<int, int>; // works
}

我想知道这两种情况有何不同?导入方式的using指令的位置是否重要?
4个回答

6
我曾认为这并不重要,但我总是完全使用命令进行资格认定。
编辑:查看C#规范,第9.4节指出:

using-directive的作用域明确不包括其同级using-directive。因此,同级using-directive不会相互影响,它们编写的顺序也不重要。

因此,如果System.Collections.Generic和KeyValuePair被视为同级,则KeyValuePair将忽略System.Collections.Generic。

5
是的,它确实有一定程度的影响。与作用域/局部名称有关的边缘情况,请参见Eric Lippert的博客
具体示例(特定于别名使用):
using System;
using Foo = Bar;
public static class Bar {
    public  static void Test() { Console.WriteLine("outer"); }
}
namespace MyNamespace {
    //using Foo = Bar;

    public static class Bar {
        public static void Test() { Console.WriteLine("inner"); }
    }
    static class Program {
        static void Main() {
            Foo.Test();
        }
    }
}

1

是的,我有一个工作示例,与类似的问题(命名空间冲突)相关。

实质上,如果使用指令是全局的(在命名空间之外),或者在命名空间内时,名称查找规则是不同的,当它具有更高的优先级。


1

这仅仅是信息性的,是针对其中一个回复声称它会影响程序集加载时间,但实际上,程序集在第一次 JITted(或通过反射等方式访问)使用它们的方法/类型时被加载。

这里有一个示例,显示它不会有任何差别;无论 using 出现在哪个位置,输出都相同:System.Core 在 JITted Bar 时被加载:

pre-Bar
System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
pre-Max
Max: 5
post-Max
post-Bar

示例(在命令行中运行,而不是在调试器中;最好使用发布配置):

using System;
//using System.Linq;
namespace Foo {
    using System.Linq;
    class Program {
        static Program() {
            AppDomain.CurrentDomain.AssemblyLoad += (s, a) => {
                Console.WriteLine(a.LoadedAssembly.FullName);
            };
        }
        static void Main() {            
            Console.WriteLine("pre-Bar");
            Bar();
            Console.WriteLine("post-Bar");
            Console.ReadLine();
        }
        static void Bar() {
            Console.WriteLine("pre-Max");
            int[] data = { 1, 2, 3, 4, 5 };
            Console.WriteLine("Max: " + Enumerable.Max(data));
            Console.WriteLine("post-Max");
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接