Влияет ли расположение директивы using на C #? - PullRequest
5 голосов
/ 13 января 2009

Сегодня я получил ошибку при попытке выполнить некоторое форматирование существующего кода. Первоначально код имел директивы 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 голосов
/ 13 января 2009

Раньше я думал, что это не имеет значения, но я всегда полностью готов к использованию команд.

Редактировать: проверил C # spec , раздел 9.4 говорит, что:

В сферу применения директивы using, в частности, не входят ее директивы using. Таким образом, одноранговые директивы использования не влияют друг на друга, и порядок их написания незначителен.

Так что, если System.Collections.Generic и KeyValuePair рассматриваются как одноранговые, то KeyValuePair будет игнорировать System.Collections.Generic.

5 голосов
/ 13 января 2009

Да, это так - в небольшой степени. Существует крайний случай, связанный с областными / местными именами, см. блог Эрика Липперта .

Для конкретного примера (в зависимости от использования псевдонима):

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 голос
/ 13 января 2009

Это чисто информационное сообщение, в котором говорится, что оно влияет на время загрузки сборки; но на самом деле сборки загружаются в первый раз, когда метод / тип, использующий их, подвергается JITted (или доступ через отражение и т. д.)

Вот пример, показывающий, что это не имеет значения; с using в любом месте вывод одинаков: System.Core загружается, когда Bar получает JITted:

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");
        }
    }
}
1 голос
/ 13 января 2009

Да, у меня есть рабочий пример с похожим вопросом (столкновения пространства имен) .

По сути, правила поиска имен различны, если директива using глобальная (вне пространства имен) или внутри пространства имен, когда она имеет более высокий приоритет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...