почему это пространство имен разрешается правильно?

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

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

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

2 ответа

5
Лучший ответ

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

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

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

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

3

В С#, когда вы находитесь в пространстве имен, вы используете неявное 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

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

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

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

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню