Чтение онлайн

ЖАНРЫ

C# для профессионалов. Том II

Ватсон Карли

Шрифт:

 public class Example {

public Example {

}

 }

}

Преимущество использования скобок для явного ограничения пространства имен состоит в том, что это задает определенный пользователем тип в реальном классе, определенном в файле, а не в самом файле. В Java файлы и папки косвенно представляют структуры языка, так как они аналогичны классам и пакетам, содержащим эти классы. В C# файлы не связаны принудительно с чем-либо, поэтому они становятся местом, где располагается определение класса, а не частью какой-либо структуры языка. Пространства имен также не связаны с папками. Следовательно, в одном файле можно ввести несколько пространств имен без всяких ограничений. Можно, например,

добавить определение нового класса и поместить его в новое пространство имен в том же файле и по-прежнему оставаться в границах языка:

// namespace_samples.cs

namespace Samples.On {

 using System;

 public class Example {

public Example {

}

 }

}

namespace Com.Cslib {

 using System;

 using System.Collections;

 public class AddLib {

public AddLib {

}

public int operationAdd(int a, int b) {

return a + b;

}

 }

}

Пространства имен вводятся с помощью директивы

using <namespace name>
, где
<namespace name>
является именем пространства имен. В C# не требуется использовать
*
, так как директива
using
неявно импортирует все элементы указанного пространства имен. Другим преимуществом является то, что пространства имен могут быть добавлены исключительно в конкретный класс. Хотя классы
Example
и
AddLib
выше определены в файле
namespace_samples.cs
.
Example
не имеет доступа к пространству имен
System.Collections
, несмотря на то, что
AddLib
его имеет. Однако инструкция
import
из Java не является специфической для класса. Она импортирует указанные элементы в файл. Вновь обратимся к
х.java
.

// х.java

public class x {

}

class у {

}

class z {

}

Если добавить инструкцию импорта, такую как

import java.util.Hashtable
, все классы, определенные внутри этого файла, будут иметь доступ к классу
Hashtable
. Код ниже будет компилироваться:

// x.java

package samples;

import java.util.Hashtable;

public class x {

 Hashtable hash = new Hashtable;

}

class у {

 Hashtable hash = new Hashtable;

}

class z {

 Hashtable hash = new Hashtable;

}

Пространства имен можно также определять внутри другого пространства имен. Этот тип гибкости недоступен в Java без создания подкаталогов. Приведенное выше пространство

Com.Cslib
можно расширить следующим образом:

namespace Com.Cslib {

 using System;

 public class AddLib {

public AddLib {

}

public int operationAdd(int a, int b) {

return a + b;

}

 }

 namespace Ext {

public class AddLib {

public AddLib {

}

public int operationAdd(int a, int b) {

return a + b;

}

}

 }

}

Пакет Java

com.javalib
можно расширить, чтобы отобразить приведенный выше код, создав новую папку
\EXT
в каталоге
com\javalib
. В этой папке создается файл исходного кода
AddLib.java
следующим образом:

package com.javalib.ext;

public class AddLib {

 public AddLib {

 }

 public int operationAdd(int a, int b) {

return a + b;

 }

}

Отметим, что имя пакета было расширено для этого класса до

com.javalib.ext
.

Внутреннее пространство имен и подпакеты доступны с помощью оператора точки "."; следовательно, можно было в C# извлечь расширенный AddLib с помощью нотации

Com.Cslib.Ext.AddLib
. В Java можно было бы использовать
com.javalib.ext.AddLib
.

Приведенный выше пример показывает одно сходство между пакетами Java и пространствами имен C#. Даже если они не используются для внешнего представления, пространства имен, так же как и пакеты, предоставляют прекрасный способ создания глобально уникальных типов, свою собственную песочницу в мире сборок независимых поставщиков. В той степени насколько это имеет отношение к C#,

Com.Cslib.AddLib
является не тем же классом, что и
Com.Cslib.Ext.AddLib
.

Классы Java являются частью пакета, нравится им это или нет. Все классы, созданные без указания пакета, предполагают включение в пакет по умолчанию. C# имитирует эту функциональность. Даже если не объявить пространство имен, оно будет создано по умолчанию. Оно присутствует в каждом файле и доступно для использования в именованных пространствах имен. Так же как в Java нельзя изменить информацию о пакете, пространства имен нельзя модифицировать. Пакеты могут охватывать несколько файлов в одной папке, пространство имен может охватывать несколько файлов в любом числе папок и даже в нескольких сборках (сборки будут рассмотрены в следующем разделе). Два класса, охватываемые пространством имен А, которые определены в отдельных файлах и существуют в отдельных папках, оба являются частью пространства имен А.

Чтобы получить доступ к элементу в пространстве имен, необходимо либо использовать полностью квалифицированное имя типа (в приведенном выше примере это

Com.Cslib.AddLib
) или импортировать элемент пространства имен в текущее пространство имен, используя директиву
using
. Отметим, что по умолчанию доступность типов данных внутри пространства имен является внутренней. Необходимо явно отметить типы данных как открытые (
public
), если требуется сделать их доступными без полной квалификации, но придерживаться такой стратегии строго не рекомендуется. Никакие другие модификаторы доступа не разрешены. В Java внутренние типы пакета могут также помечаться как
final
или
abstract
, или не помечаться вообще (этот доступ по умолчанию открывает их только для потребителей внутри пакета). Модификаторы доступа будут рассматриваться позже в этом приложении.

Последним атрибутом, который относится к пространству имен, но не имеет отношения к пакетам, является возможность задания алиаса для

using
. Алиасы
using
существенно облегчают квалификацию идентификатора для пространства имен или класса. Синтаксис очень простой. Предположим, что имеется пространство имен
Very.Very.Long.Namespace.Name
. Можно определить и использовать алиас
using
для пространства имен следующим образом:

using WLNN = Very.Very.Long.Namespace.Name;

Поделиться с друзьями: