Home Random Page


CATEGORIES:

BiologyChemistryConstructionCultureEcologyEconomyElectronicsFinanceGeographyHistoryInformaticsLawMathematicsMechanicsMedicineOtherPedagogyPhilosophyPhysicsPolicyPsychologySociologySportTourism






checked и unchecked

Операторы checked и unchecked используются для управления контекстом контроля переполнения в арифметических операциях и преобразованиях целых типов.

оператор_checked:
checked блок

оператор_unchecked:
unchecked блок

Оператор checked задает вычисление всех выражений в блоке в проверяемом контексте, а оператор unchecked задает вычисление всех выражений в блоке в непроверяемом контексте.

Операторы языка checked и unchecked в точности эквивалентны операторам выражений checked и unchecked (§7.6.12), только они применяются к блокам, а не к выражениям.

Lock

Оператор lock устанавливает взаимоисключающую блокировку для заданного объекта, выполняет оператор языка и затем снимает блокировку.



оператор_lock:
lock ( выражение ) внедренный_оператор

Выражение оператора lock должно представлять значение, тип которого точно является ссылочным_типом. Для выражения оператора lock никогда не выполняется неявное преобразование с упаковкой (§6.1.7); использование выражения для представления значения, тип которого является типом_значения, вызывает ошибку времени компиляции.

Оператор lock следующего вида:

lock (x) ...

где x — выражение ссылочного_типа, в точности эквивалентен записи

System.Threading.Monitor.Enter(x);
try {
...
}
finally {
System.Threading.Monitor.Exit(x);
}

за исключением того, что x вычисляется только один раз.

При установленной взаимоисключающей блокировке код, выполняемый в том же потоке выполнения, также может установить и снять блокировку. Однако код, выполняемый в других потоках, не сможет установить блокировку, пока не будет снята данная блокировка.

Не рекомендуется блокировать объекты System.Type для синхронизации доступа к статическим данным. Этот же тип может быть заблокирован другим кодом, что приведет к взаимоблокировке. Синхронизировать доступ к статическим данных лучше путем блокировки закрытого статического объекта. Пример:

class Cache
{
private static readonly object synchronizationObject = new object();

public static void Add(object x) {
lock (Cache.synchronizationObject) {
...
}
}

public static void Remove(object x) {
lock (Cache.synchronizationObject) {
...
}
}
}

Using

Оператор using получает один или несколько ресурсов, выполняет заданный оператор языка и затем удаляет ресурсы.

оператор_using:
using ( выделение_ресурса ) внедренный_оператор

получение_ресурса:
объявление_локальной_переменной
выражение

Ресурс — это класс или структура, реализующая интерфейс System.IDisposable, который состоит из одного метода без параметров с именем Dispose. Код, использующий ресурс, может вызвать метод Dispose, чтобы показать, что ресурс больше не нужен. Если не вызывать метод Dispose, ресурс будет в итоге удален автоматически в результате сборки мусора.

Если выделение_ресурса задано как объявление_локальной_переменной, то типом объявления_локальной_переменной должен быть тип dynamic или тип, допускающий неявное преобразование в System.IDisposable. Если выделение_ресурса задано как выражение, то это должно быть выражение типа, допускающего неявное преобразование в System.IDisposable.

Локальные переменные, объявленные при выделении_ресурса, доступны только на чтение и должны включать инициализатор. Если внедренный оператор пытается изменить эти локальные переменные (путем присваивания или с помощью операторов ++ и ‑‑), получить их адрес или передать их как параметры ref или out, возникает ошибка времени компиляции.

Процесс оператора using состоит из трех частей: выделение ресурса, использование и удаление. Использование ресурса неявно включается в оператор try с предложением finally. Это предложение finally удаляет ресурс. Если выделяется ресурс null, метод Dispose не вызывается и исключение не генерируется. Если ресурс имеет тип dynamic, это означает, что он динамически преобразован путем неявного динамического преобразования (§6.1.8) к IDisposable в процессе выделения с целью обеспечения успешного преобразования перед использованием и удалением.

Оператор using в виде

using (ResourceType resource = expression) statement

может быть развернут тремя способами. Если ResourceType имеет необнуляемый тип значения, выражение имеет вид

{
ResourceType resource = expression;
try {
statement;
}
finally {
((IDisposable)resource).Dispose();
}
}

Если же ResourceType является обнуляемым типом значения или ссылочным типом (за исключением dynamic), оператор развертывается следующим образом:

{
ResourceType resource = expression;
try {
statement;
}
finally {
if (resource != null) ((IDisposable)resource).Dispose();
}
}

В противном случае, если ResourceType является типом dynamic, оператор развертывается так:

{
ResourceType resource = expression;
IDisposable d = (IDisposable)resource;
try {
statement;
}
finally {
if (d != null) d.Dispose();
}
}

В обоих случаях переменная resource доступна только для чтения во внедренном операторе, а переменная d недоступна и невидима для внедренного оператора.

В реализации разрешается выполнять реализацию определенного оператора using иным образом (например, для повышения быстродействия), при условии сохранения поведения, совместимого с вышеописанным развертыванием.

Оператор using в виде

using (expression) statement

может развертываться теми же тремя способами, но на этот раз в качестве ResourceType неявно принимается тип выражения expression, определяемый во время компиляции, а переменная resource недоступна и невидима для внедренного оператора.

Если выделение_ресурса задано в виде объявления_локальной_переменной, можно выделить несколько ресурсов данного типа. Оператор using в виде

using (ResourceType r1 = e1, r2 = e2, ..., rN = eN) statement

в точности эквивалентен последовательности вложенных операторов using:

using (ResourceType r1 = e1)
using (ResourceType r2 = e2)
...
using (ResourceType rN = eN)
statement

В следующем примере создается файл log.txt и в него записываются две строки текста. Затем тот же файл открывается для чтения, и содержащиеся в нем строки текста выводятся на консоль.

using System;
using System.IO;

class Test
{
static void Main() {
using (TextWriter w = File.CreateText("log.txt")) {
w.WriteLine("This is line one");
w.WriteLine("This is line two");
}

using (TextReader r = File.OpenText("log.txt")) {
string s;
while ((s = r.ReadLine()) != null) {
Console.WriteLine(s);
}

}
}
}

Поскольку классы TextWriter и TextReader реализуют интерфейс IDisposable, в примере можно использовать оператор using для того, чтобы гарантировать корректное закрытие обрабатываемого файла после операций чтения или записи.

Yield

Оператор yield используется в блоке итератора (§8.2) для выдачи значения в объект перечислителя (§10.14.4) или в перечислимый объект итератора (§10.14.5), либо для сигнализации об окончании итерации.

оператор_yield:
yield return выражение ;
yield break ;

yield не является зарезервированным словом; оно приобретает особый смысл только тогда, когда стоит непосредственно перед ключевым словом return или break. В других контекстах yield может использоваться как идентификатор.

На использование оператора yield накладывается ряд ограничений.

· Использование оператора yield (в любой из двух форм) вне тела_метода, тела_оператора или тела_метода_доступа вызывает ошибку времени компиляции.

· Использование оператора yield (в любой из двух форм) внутри анонимной функции вызывает ошибку времени компиляции.

· Использование оператора yield (в любой из двух форм) в предложении finally оператора try вызывает ошибку времени компиляции.

· Использование оператора yield return в любом месте оператора try, содержащего предложения catch, вызывает ошибку времени компиляции.

В следующем примере демонстрируется несколько допустимых и недопустимых способов использования оператора yield.

delegate IEnumerable<int> D();

IEnumerator<int> GetEnumerator() {
try {
yield return 1; // Ok
yield break; // Ok
}
finally {
yield return 2; // Error, yield in finally
yield break; // Error, yield in finally
}

try {
yield return 3; // Error, yield return in try...catch
yield break; // Ok
}
catch {
yield return 4; // Error, yield return in try...catch
yield break; // Ok
}

D d = delegate {
yield return 5; // Error, yield in an anonymous function
};
}

int MyMethod() {
yield return 1; // Error, wrong return type for an iterator block
}

Должно существовать неявное преобразование (§6.1) типа выражения оператора yield return в тип выдачи итератора (§10.14.3).

Оператор yield return выполняется следующим образом.

· Выражение, заданное в операторе, вычисляется, неявно преобразуется к типу yield и присваивается свойству Current объекта перечислителя;

· Выполнение блока итератора приостанавливается. Если оператор yield return находится внутри одного или более блоков try, их соответствующие блоки finally не выполняются в это время;

· Метод MoveNext объекта перечислителя возвращает true в вызвавшую его программу, тем самым указывая на успешный переход объекта перечислителя к следующему элементу.

Следующий вызов метода MoveNext объекта перечислителя возобновляет выполнение блока итератора с того места, где оно было приостановлено.

Оператор yield break выполняется следующим образом.

· Если оператор yield break входит в один или несколько блоков try, с которыми связаны соответствующие блоки finally, управление вначале передается в блок finally самого внутреннего оператора try. Если управление достигает конечной точки блока finally, после этого управление передается в блок finally следующего объемлющего оператора try. Этот процесс повторяется до тех пор, пока не будут выполнены все блоки finally всех объемлющих операторов try.

· Управление возвращается в метод, вызвавший блок итератора. Это либо метод MoveNext, либо метод Dispose объекта перечислителя.

Поскольку оператор yield осуществляет безусловную передачу управления в другое место, конечная точка оператора yield никогда не будет достижима.


 

9. Пространства имен

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

Директивы using (§9.4) служат для упрощения использования пространств имен.

9.1 Единицы компиляции

Единица_компиляции определяет общую структуру исходного файла. Единица компиляции состоит из 0 или более директив_using, за которыми следуют 0 или более глобальных_атрибутов, за которыми следуют 0 или более объявлений_членов_пространства_имен.

единица_компиляции:
директивы_extern_aliasнеобязательно директивы_usingнеобязательно глобальные_атрибутынеобязательно
объявления_членов_пространства_именнеобязательно

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

Директивы_using единицы компиляции влияют на глобальные_атрибуты и объявления_членов_пространства_имен этой единицы компиляции, но не влияют на другие единицы компиляции.

Глобальные_атрибуты (§17) единицы компиляции разрешают спецификацию атрибутов для конечной сборки и модуля. Сборки и модули действуют как физические контейнеры для типов. Сборка может состоять из нескольких физически отдельных модулей.

Объявления_членов_пространства_имен каждой единицы компиляции программы размещают члены в одной области объявления, называемой глобальным пространством имен. Например:

Файл A.cs:

class A {}

Файл B.cs:

class B {}

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

9.2 Объявления пространства имен

Объявление_пространства_имен состоит из ключевого слова namespace, за которым следует имя и тело пространства имен, а затем точка с запятой (необязательно).

объявление_пространства_имен:
namespace уточненный_идентификатор тело_пространства_имен ;необ

проверенный_идентификатор:
идентификатор
проверенный_идентификатор . идентификатор

тело_пространства_имен:
{ директивы_внешних_псевдонимовнеобязательно директивы_usingнеобязательно объявления_элементов_пространства_именнеобязательно }

Объявление_пространства_имен может быть объявлением верхнего уровня в единице_компиляции или объявлением члена внутри другого объявления_пространства_имен. Если объявление_пространства_имен встречается как объявление верхнего уровня в единице_компиляции, это пространство имен становится членом глобального пространства имен. Если объявление_пространства_имен встречается внутри другого объявления_пространства_имен, внутреннее пространство имен становится членом внешнего пространства имен. В обоих случаях имя пространства имен долk


Date: 2015-12-11; view: 713


<== previous page | next page ==>
From, let, where, join и orderby 1 page | Masculino y femenino.
doclecture.net - lectures - 2014-2024 year. Copyright infringement or personal data (0.012 sec.)