`using`指令的位置是否会对C#产生影响?

时间:2009-01-13 08:37:36

标签: c# syntax

我在尝试对现有代码进行格式化时遇到错误。最初,代码在命名空间之外声明了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
}

我想知道两种情况之间有什么区别? (import-style)using指令的位置是否重要?

4 个答案:

答案 0 :(得分:6)

我曾经认为这无所谓,但我总是完全符合使用命令。

编辑:选中C# spec,第9.4节说:

  

using-directive的范围特别不包括其peer-directives。因此,peer using-directives不会相互影响,并且它们的编写顺序无关紧要。

因此,如果将System.Collections.Generic和KeyValuePair视为对等,则KeyValuePair将忽略System.Collections.Generic。

答案 1 :(得分:5)

是的,它确实 - 在很小程度上。有一个与范围/本地名称有关的边缘情况,请参阅Eric Lippert's blog

有关具体示例(特定于别名用法):

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();
        }
    }
}

答案 2 :(得分:1)

是的,我有一个类似working examplequestion (Namespace collisions)

本质上,如果using指令是全局的(在命名空间之外)或在命名空间中取得更高的优先级时,名称查找的规则是不同的。

答案 3 :(得分:1)

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

这是一个显示它没有区别的例子;在任一位置使用using,输出都是相同的:System.CoreBar获取JIT时加载:

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");
        }
    }
}