Студопедия — Checked и unchecked
Студопедия Главная Случайная страница Обратная связь

Разделы: Автомобили Астрономия Биология География Дом и сад Другие языки Другое Информатика История Культура Литература Логика Математика Медицина Металлургия Механика Образование Охрана труда Педагогика Политика Право Психология Религия Риторика Социология Спорт Строительство Технология Туризм Физика Философия Финансы Химия Черчение Экология Экономика Электроника

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необязательно объявления_элементов_пространства_именнеобязательно }

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







Дата добавления: 2015-09-07; просмотров: 500. Нарушение авторских прав; Мы поможем в написании вашей работы!



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

Расчетные и графические задания Равновесный объем - это объем, определяемый равенством спроса и предложения...

Кардиналистский и ординалистский подходы Кардиналистский (количественный подход) к анализу полезности основан на представлении о возможности измерения различных благ в условных единицах полезности...

Обзор компонентов Multisim Компоненты – это основа любой схемы, это все элементы, из которых она состоит. Multisim оперирует с двумя категориями...

Характерные черты официально-делового стиля Наиболее характерными чертами официально-делового стиля являются: • лаконичность...

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

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

Вопрос 1. Коллективные средства защиты: вентиляция, освещение, защита от шума и вибрации Коллективные средства защиты: вентиляция, освещение, защита от шума и вибрации К коллективным средствам защиты относятся: вентиляция, отопление, освещение, защита от шума и вибрации...

Задержки и неисправности пистолета Макарова 1.Что может произойти при стрельбе из пистолета, если загрязнятся пазы на рамке...

Вопрос. Отличие деятельности человека от поведения животных главные отличия деятельности человека от активности животных сводятся к следующему: 1...

Studopedia.info - Студопедия - 2014-2024 год . (0.013 сек.) русская версия | украинская версия