Пространства имен в C # против импорта в Java и Python - PullRequest
11 голосов
/ 22 сентября 2010

В мире Java и Python вы смотрите на исходный файл и знаете, откуда происходит весь импорт (т.е. вы знаете, в каком файле определены импортируемые классы). Например:

В Java:

import javafoo.Bar;

public class MyClass {
    private Bar myBar = new Bar();
}

Вы сразу видите, что Bar-класс импортирован из javafoo. Итак, Бар объявлен в /javafoo/Bar.java

В Python

import pythonbaz
from pythonfoo import Bar

my_bar = Bar()
my_other = pythonbaz.Other()

Здесь ясно, что Bar происходит из пакета pythonfoo, а Other явно из pythonbaz.

В C # (поправьте меня, если я ошибаюсь):

using foo
using baz
using anothernamespace
...

public class MyClass
{
    private Bar myBar = new Bar();
}

Два вопроса:
1) Как узнать, где объявлен Бар-класс? Это происходит из пространства имен foo, или bar, или anothernamespace? (изменить: без с использованием Visual Studio)

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

В C #, похоже, нет такого соглашения для пространств имен, или я что-то упустил? Итак, как мне узнать, какой каталог и файл искать (без Visual Studio)? (после выяснения, из какого пространства имен появился класс).

Редактировать пояснение : Мне известно, что Python и / или Java разрешают импорт подстановочных знаков, но «культура» в этих языках осуждается на них (по крайней мере в Python, в Java я не уверен) , Кроме того, в Java IDE обычно помогают создавать минимальный импорт (как прокомментировал Mchl. Ниже)

Ответы [ 6 ]

7 голосов
/ 22 сентября 2010

1) Ну, вы можете сделать то же самое и в Java:

import java.util.*;
import java.io.*;

...

InputStream x = ...;

InputStream взято из java.util или java.io? Конечно, вы можете не использовать эту функцию.

Теперь, в теории Я понимаю, что это означает, что когда вы просматриваете текстовый редактор, вы не можете сказать, откуда берутся типы в C # ... но на практике я не найти это быть проблемой. Как часто вы на самом деле смотрите на код и не можете использовать Visual Studio?

2) Конечно, вы можете использовать то же соглашение и в .NET - и я использую, хотя у меня нет пустых каталогов, идущих вверх по цепочке ... так что, если я создаю проект с пространством имен по умолчанию XY, тогда X.Y.Foo будет в Foo.cs, а XYZBar будет в Z\Bar.cs

Это также то, что Visual Studio будет делать по умолчанию - если вы создадите подпапку, она создаст новые классы, используя пространство имен на основе проекта по умолчанию и структуры папок.

Конечно, вы также можете объявлять типы в любом старом файле - но в основном люди будут следовать обычному соглашению об объявлении типа с соответствующим именем файла. До того как дженерики делали объявления делегатов более редкими, у меня был файл Delegates.cs, содержащий все объявления делегатов для определенного пространства имен (а не набор файлов с одиночным объявлением), но в наши дни это не проблема.

3 голосов
/ 22 сентября 2010

1) Ты прав. На первый взгляд нет «прямого» способа узнать, откуда взялся ваш класс, но, как вы сказали, вы можете перейти к нему в IDE. Но объявление класса таким образом - самый короткий способ сделать это. Если вы хотите, и если ваш класс Bar принадлежит классу Foo, вы можете объявить его

private foo.Bar myBar = new foo.Bar();

Таким образом, с первого взгляда было бы полезно знать, откуда берутся ваши уроки.

2) Когда вы добавляете ссылку на ваш класс, окна Добавить ссылку предоставляют вам информацию, которую вы ищете. И если вы хотите узнать, откуда они берутся после того, как вы объявили это, есть окно с именем «Solution Explorer», где вы можете найти эту информацию, под узлом дерева «References». Вы можете установить его всегда видимым (что по умолчанию)

2 голосов
/ 22 сентября 2010

Для Java и Python это действительно проблема с соглашениями - импортируйте нужный класс, а не весь пакет с использованием подстановочных знаков.

В C # вы не можете выполнить директиву using для определенного класса, который вам нужен, поскольку он работает только для пространств имен (как показывает следующая ошибка). Казалось бы, C # остался верен концепции C ++ о пространствах имен и объединил ее с директивой #include для одного простого способа ссылки на внешние классы.

using System.Net.Sockets.Socket; // Gives the following error:

// A using namespace directive can only be applied to namespaces; 
// 'System.Net.Sockets.Socket' is a type not a namespace

А насчет двойного Bar замедления, все просто - если компилятор не может знать, что он выдаст ошибку:

using Foo; // Has class Bar {}
using Goo; // Has class Bar {}

Bar b = new Bar(); // Gives the following error:
// 'Bar' is an ambiguous reference between 'Foo.Bar' and 'Goo.Bar'
2 голосов
/ 22 сентября 2010

В C #, похоже, нет такого соглашения для пространств имен, или я что-то упустил?

Я не знаю о других проектах, но я почти уверенчто в каждом проекте .NET, над которым я работал, мы использовали это соглашение, то есть пространства имен всегда соответствовали именам папок (за исключением самых внешних пространств имен, которые соответствуют сборке, из которой происходит пространство имен).

2 голосов
/ 22 сентября 2010

Как я узнаю, где находится Бар-класс? объявили? Это исходит от пространство имен foo, или bar, или anothernamespace? Visual Studio позволяет я там прыгну, конечно, но что если я просто взгляну на Исходный файл в моем редакторе?

По сути, вы этого не делаете, но IntelliSense помогает. На самом деле вы не можете быть уверены, просто взглянув на код, но вы можете, например, навести курсор на символ курсором. Но это также возможно в Python:

from foobar import *
from bazbaz import *

a_bar = Bar()

Откуда сейчас появился Бар?

В C # вроде нет такого соглашение о пространствах имен, или я что-то упустил? Итак, как я знаю какой каталог и файл искать? (после выяснения, какое пространство имен класс пришел)

Нет, сборки не соответствуют структурам каталогов, что, IMHO, хорошо. Обозреватель решений предлагает просмотр всех ссылок, добавленных в ваш проект. Эти ссылки, являющиеся сборками, имеют конкретное представление в виде PE-файла где-то на вашем компьютере. Вы можете легко просмотреть свойства ссылки, чтобы увидеть, где находится физический файл.

Редактировать: Чтобы не противоречить другим ответам в этой теме и создать путаницу: я имею в виду, говоря, что имена сборок не соответствуют именам каталогов, так как они фактически не применяются.

1 голос
/ 22 сентября 2010

Обычно всплывающая подсказка при наведении указателя мыши на имя типа отображает некоторую дополнительную информацию. В противном случае вы всегда можете щелкнуть правой кнопкой мыши имя типа и «Перейти к определению».

...