Должны ли директивы using находиться внутри или вне пространства имен?

Это поведение было выбрано, потому что в противном случае jQuery будет регулярно генерировать исключения NullReference

. Почти все функции jQuery возвращают объект jQuery в качестве обертки вокруг элементов Dom, поэтому вы можете использовать точечную нотацию.

$("#balloon").css({"color":"red"});

Теперь представьте, что $("#balloon") возвратил null . Это означает, что $("#balloon").css({"color":"red"}); выдаст ошибку, вместо того, чтобы молча делать ничего, как вы ожидали.

Следовательно, вы просто должны использовать .length или .size().

1916
задан Philippe 13 April 2018 в 11:44
поделиться

4 ответа

Существует на самом деле (тонкое) различие между двумя. Предположите, что у Вас есть следующий код в File1.cs:

// File1.cs
using System;
namespace Outer.Inner
{
    class Foo
    {
        static void Bar()
        {
            double d = Math.PI;
        }
    }
}

Теперь предполагают, что кто-то добавляет другой файл (File2.cs) к проекту, который похож на это:

// File2.cs
namespace Outer
{
    class Math
    {
    }
}

поиски компилятора Outer перед рассмотрением тех using директивы вне пространства имен, таким образом, это находит Outer.Math вместо System.Math. К сожалению (или возможно к счастью?), Outer.Math не имеет никакого PI участник, таким образом, File1 теперь повреждается.

Это изменяется, если Вы помещаете using внутренняя часть Ваше объявление пространства имен, следующим образом:

// File1b.cs
namespace Outer.Inner
{
    using System;
    class Foo
    {
        static void Bar()
        {
            double d = Math.PI;
        }
    }
}

Теперь поиски компилятора System прежде, чем искать Outer, находит System.Math, и все хорошо.

Некоторые утверждали бы, что Math могла бы быть дурная слава для пользовательского класса, так как уже существует один в [1 114]; точка здесь просто, что там различие, и она влияет на пригодность для обслуживания Вашего кода.

также интересно отметить то, что происходит, если Foo находится в пространстве имен Outer, а не Outer.Inner. В этом случае добавление Outer.Math в File2 повреждает File1 независимо от того, куда эти using идет. Это подразумевает, что компилятор ищет самое внутреннее пространство имен включения, прежде чем это посмотрит на любой using директива.

1999
ответ дан Philippe 13 April 2018 в 11:44
поделиться

Помещение его в пространствах имен делает объявления локальными для того пространства имен для файла (в случае, если у Вас есть несколько пространств имен в файле), но если у Вас только есть одно пространство имен на файл тогда, это не имеет большую часть значения, выходят ли они на улицу или в пространстве имен.

using ThisNamespace.IsImported.InAllNamespaces.Here;

namespace Namespace1
{ 
   using ThisNamespace.IsImported.InNamespace1.AndNamespace2;

   namespace Namespace2
   { 
      using ThisNamespace.IsImported.InJustNamespace2;
   }       
}

namespace Namespace3
{ 
   using ThisNamespace.IsImported.InJustNamespace3;
}
189
ответ дан Mark Cidade 13 April 2018 в 11:44
поделиться

Согласно Hanselman - Используя Директиву и Загрузку блока... и другие такие статьи там не технически никакое различие.

Мое предпочтение должно поместить их за пределами пространств имен.

62
ответ дан Quintin Robinson 13 April 2018 в 11:44
поделиться

Согласно документации StyleCop:

SA1200: UsingDirectivesMustBePlacedWithinNamespace

Причина Директива AC # using помещается вне элемента пространства имен.

Описание правила Нарушение этого правила происходит, когда директива using или директива using-alias размещается вне элемента пространства имен, если файл не содержит никаких элементов пространства имен.

Например, следующий код приведет к двум нарушениям этого rule.

using System;
using Guid = System.Guid;

namespace Microsoft.Sample
{
    public class Program
    {
    }
}

Однако следующий код не приведет к каким-либо нарушениям этого правила:

namespace Microsoft.Sample
{
    using System;
    using Guid = System.Guid;

    public class Program
    {
    }
}

Этот код будет компилироваться чисто, без каких-либо ошибок компилятора. Однако неясно, какая версия типа Guid выделяется. Если директива using перемещается внутрь пространства имен, как показано ниже, возникает ошибка компилятора:

namespace Microsoft.Sample
{
    using Guid = System.Guid;
    public class Guid
    {
        public Guid(string s)
        {
        }
    }

    public class Program
    {
        public static void Main(string[] args)
        {
            Guid g = new Guid("hello");
        }
    }
}

Код не работает из-за следующей ошибки компилятора, найденной в строке, содержащей Guid g = new Guid ("hello" );

CS0576: Пространство имен 'Microsoft.Sample' содержит определение, конфликтующее с псевдонимом 'Guid'

Код создает псевдоним типа System.Guid с именем Guid, а также создает собственный тип с именем Guid с соответствующим интерфейсом конструктора. Позже код создает экземпляр типа Guid. Чтобы создать этот экземпляр, компилятор должен выбрать между двумя разными определениями Guid. Когда директива using-alias размещается вне элемента пространства имен, компилятор выбирает локальное определение Guid, определенное в локальном пространстве имен, и полностью игнорирует директиву using-alias, определенную вне пространства имен. Это, к сожалению, не очевидно при чтении кода.

Однако, когда директива using-alias помещается в пространство имен, компилятор должен выбирать между двумя разными конфликтующими типами Guid, которые определены в одном пространстве имен. Оба эти типа предоставляют соответствующий конструктор. Компилятор не может принять решение, поэтому он отмечает ошибку компилятора.

Размещение директивы using-alias за пределами пространства имен является плохой практикой, потому что это может привести к путанице в таких ситуациях, как эта, где это неочевидно. какая версия типа действительно используется. Это потенциально может привести к ошибке, которую может быть трудно диагностировать.

Размещение директив using-alias в элементе пространства имен устраняет это как источник ошибок.

  1. Несколько пространств имен

Размещение нескольких элементов пространства имен в одном файле, как правило, является плохой идеей, но если и когда это будет сделано, рекомендуется разместить все директивы using внутри каждого из элементов пространства имен, а не глобально вверху файла. Это сильно ограничит пространство имен, а также поможет избежать описанного выше поведения.

Важно отметить, что когда код был написан с использованием директив, размещенных вне пространства имен, следует проявлять осторожность при перемещении этих директив в пространстве имен, чтобы гарантировать, что это не изменит семантику кода. Как объяснялось выше, размещение директив using-alias в элементе пространства имен позволяет компилятору выбирать между конфликтующими типами способами, которые не будут происходить, если директивы размещены за пределами пространства имен.

Как исправить нарушения. Чтобы устранить нарушение этого правила, переместите все директивы using и директивы using-alias в элемент пространства имен.

48
ответ дан 22 November 2019 в 20:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: