2014-11-14 2 views
1

Я просто смотрю на проект, и я вижу что-то работающее, которое, как я думал, не должно работать.Почему это пространство имен правильно разрешено?

Если посмотреть на фрагмент ниже я нахожусь в пространстве имен CustomFields.DateTimeField.Drivers, и только другие using заявления в этом файле и другие пространства имен нижеCustomFields.DateTimeField.

Но если вы посмотрите на строку public class DateTimeFieldDriver, то используется тип Fields.DateTimeField.

Глядя на определение DateTimeField thats в пространстве имен CustomFields.DateTimeField.Fields, но я только установил для своих сестринских пространств имена.

Итак, вопрос двоякий - почему это работает? это считается плохой практикой?

сниппета в вопросе:

using System; 
using JetBrains.Annotations; 
using Orchard; 
using Orchard.ContentManagement; 
using Orchard.ContentManagement.Drivers; 
using Orchard.Localization; 

using CustomFields.DateTimeField.Settings; 
using CustomFields.DateTimeField.ViewModels; 

namespace CustomFields.DateTimeField.Drivers { 

    [UsedImplicitly] 
    public class DateTimeFieldDriver : ContentFieldDriver<Fields.DateTimeField> { 

     public IOrchardServices Services { get; set; } 

     private const string TemplateName = "Fields/Custom.DateTime"; // EditorTemplates/Fields/Custom.DateTime.cshtml 

     public DateTimeFieldDriver(IOrchardServices services) { 

      Services = services; 
      T = NullLocalizer.Instance; 
     } 

Проект может быть downloaded here, если вы хотите, чтобы исследовать его (MVC2 проекта).

+1

Возможно, вам стоит проверить, что MSDN может сказать по этому вопросу? Я бы предположил, что для разрешения пространства имен используется какой-то каскадный поиск. Я бы не сказал, что это плохая практика, но наличие класса с тем же именем, что и родительское пространство имен ('DateTimeField'), безусловно, считается не очень хорошим/безопасным для проверки дома. – Leandro

ответ

5

При объявлении код быть внутри определенного пространства имен, например, CustomFields.DateTimeField.Drivers, вы неявно импортирования всех «родительских» пространств имен, а также.

В этом случае у вас подразумевается использование для CustomFields и CustomFields.DateTimeField. Вот почему вам не нужно указывать явный оператор using для типов в CustomFields.DateTimeField и, кроме того, для подпространств имен, содержащихся в нем.

Таким образом Fields.DateTimeField обнаруживаются путем объединения CustomFields.DateTimeField (подразумеваемое пространство имен) с Fields.DateTimeField (явными) пространством имен для разрешения на CustomFields.DateTimeField.Fields.DateTimeField.

И нет, насколько я знаю, это не считается плохой практикой.

3

В C#, когда вы находитесь в пространстве имен, у вас есть неявный using для каждого из родительских пространств имен. Например, в этом файле:

using System; 

namespace Foo.Bar.Baz { 

    class Qux { 
    } 
} 
\EOF 

То же самое, как этот файл:

using System; 

using Foo; 
using Foo.Bar; 

namespace Foo.Bar.Baz { 

    class Qux { 
    } 
} 
\EOF 

Если пространство имен импортируется, то вам не нужно указать полное пространство имен для доступа членов родственное дерево имен при условии, что имеет тот же префикс, как импортируемое пространство имена:

using Foo; 
using Foo.Bar; 

namespace Foo.Bar.Baz { 

    class Qux { 
    } 
} 

namespace Foo.Bar.Norf { 

    class Guf : Bar.Baz.Qux { // namespace `Foo.` is implicitly assumed to prefix the namespace reference `Bar.Baz` 
    } 
} 
\EOF 

Вы испытываете эти два эффекта в сочетании: неявное использование префикса пространства имен неявно импортируемое пространство имен.

Что касается «плохой практики» - опытные разработчики C# будут знакомы с этим нюансом, но, как правило, это не проблема, если у вас есть неоднозначные имена.

В качестве подсказки попытайтесь свести к минимуму количество пространств имен и их глубин. Например, в вашем случае я вижу, что вы храните специфичные для DateTime вещи в своем собственном пространстве имен DateTimeField.У меня плохой запах кода. Я бы просто поместил все в пространство имен CustomFields, тем более, что вы все равно присвоили префикс DateTime, так что это просто двойная типизация.

FxCop будет жаловаться, если у вас меньше 5 типов в пространстве имен, кстати.

Обновление: я рассмотрел спецификацию C# (http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-334.pdf), раздел 16, но я не могу найти ее часть, которая заявляет, что родительские пространства имен импортируются неявно, что странно.

Смежные вопросы