Герберт Шилдт - C# 4.0: полное руководство
- Название:C# 4.0: полное руководство
- Автор:
- Жанр:
- Издательство:ООО И.Д. Вильямс
- Год:2011
- Город:Москва -- Киев
- ISBN:978-5-8459-1684-6
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Герберт Шилдт - C# 4.0: полное руководство краткое содержание
В этом полном руководстве по C# 4.0 - языку программирования, разработанному специально для среды .NET, - детально рассмотрены все основные средства языка: типы данных, операторы, управляющие операторы, классы, интерфейсы, методы, делегаты, индексаторы, события, указатели, обобщения, коллекции, основные библиотеки классов, средства многопоточного программирования и директивы препроцессора. Подробно описаны новые возможности C#, в том числе PLINQ, библиотека TPL, динамический тип данных, а также именованные и необязательные аргументы. Это справочное пособие снабжено массой полезных советов авторитетного автора и сотнями примеров программ с комментариями, благодаря которым они становятся понятными любому читателю независимо от уровня его подготовки.
Книга рассчитана на широкий круг читателей, интересующихся программированием на C#.Введите сюда краткую аннотацию
C# 4.0: полное руководство - читать онлайн бесплатно ознакомительный отрывок
Интервал:
Закладка:
Существует разновидность ограничения на базовый класс, позволяющая установить связь между двумя параметрами типа. В качестве примера рассмотрим следующее объявление обобщенного класса.
class Gen where V : T {
В этом объявлении оператор where
уведомляет компилятор о том, что аргумент типа, привязанный к параметру типа V, должен быть таким же, как и аргумент типа, привязанный к параметру типа Т, или же наследовать от него. Если подобная связь отсутствует при объявлении объекта типа Gen
, то во время компиляции возникнет ошибка. Такое ограничение на параметр типа называется неприкрытым ограничением типа. В приведенном ниже примере демонстрируется наложение этого ограничения.
// Установить связь между двумя параметрами типа.
using System;
class A {
//...
}
class В : A {
// ...
}
// Здесь параметр типа V должен наследовать от параметра типа Т.
class Gen where V : T {
// ...
}
class NakedConstraintDemo {
static void Main() {
// Это объявление вполне допустимо, поскольку
// класс В наследует от класса А.
Gen х = new Gen();
// А это объявление недопустимо, поскольку
// класс А-.не наследует от класса В. .
// Gen у = new Gen();
}
}
Обратите внимание на то, что класс В наследует от класса А. Проанализируем далее оба объявления объектов класса Gen
в методе Main(). Как следует из комментария к первому объявлению
Gen х = new Gen();
оно вполне допустимо, поскольку класс В наследует от класса А. Но второе объявление
// Gen у = new Gen();
недопустимо, поскольку класс А не наследует от класса В.
С параметром типа может быть связано несколько ограничений. В этом случае ограничения указываются списком через запятую. В этом списке первым должно быть указано ограничение class
либо struct
, если оно присутствует, или же ограничение на базовый класс, если оно накладывается. Указывать ограничения class
или struct
одновременно с ограничением на базовый класс не разрешается. Далее по списку должно следовать ограничение на интерфейс, а последним по порядку — ограничение new()
. Например, следующее объявление считается вполне допустимым.
class Gen where Т : MyClass, IMylnterface, new() {
// ...
В данном случае параметр типа Т должен быть заменен аргументом типа, наследующим от класса MyClass
, реализующим интерфейс IMylnterface
и использующим конструктор без параметра.
Если же в обобщении используются два или более параметра типа, то ограничения на каждый из них накладываются с помощью отдельного оператора where, как в приведенном ниже примере.
// Использовать несколько операторов where,
using System;
// У класса Gen имеются два параметра типа, и на оба накладываются
// ограничения с помощью отдельных операторов where,
class Gen where T : class
where V : struct {
T ob1;
V ob2;
public Gen(T t, V v) {
ob1 = t;
ob2 = v;
}
}
class MultipleConstraintDemo {
static void Main() {
// Эта строка кода вполне допустима, поскольку
// string — это ссылочный тип, a int — тип значения.
Gen obj = new Gen("TecT", 11);
//А следующая строка кода недопустима, поскольку
// bool не относится к ссылочному типу.
// Gencbool, int> obj = new Gencbool, int>(true, 11);
}
}
В данном примере класс Gen принимает два аргумента с ограничениями, накладываемыми с помощью отдельных операторов where. Обратите особое внимание на объявление этого класса.
class GenCT, V> where T : class
where V : struct {
Как видите, один оператор where
отделяется от другого только пробелом. Другие знаки препинания между ними не нужны и даже недопустимы.
Получение значения, присваиваемого параметру типа по умолчанию
Как упоминалось выше, при написании обобщенного кода иногда важно провести различие между типами значений и ссылочными типами. Такая потребность возникает, в частности, в том случае, если переменной параметра типа должно быть присвоено значение по умолчанию. Для ссылочных типов значением по умолчанию является null
, для неструктурных типов значений — 0 или логическое значение false
, если это тип bool
, а для структур типа struct
— объект соответствующей структуры с полями, установленными по умолчанию. В этой связи возникает вопрос: какое значение следует присваивать по умолчанию переменной параметра типа: null
, 0 или нечто другое? Например, если в следующем объявлении класса Test
:
class Test {
Т obj;
// ...
переменной obj требуется присвоить значение по умолчанию, то какой из двух вариантов
obj = null; // подходит только для ссылочных типов или
obj =0; // подходит только для числовых типов и
// перечислений, но не для структур
следует выбрать? Для разрешения этой дилеммы можно воспользоваться еще одной формой оператора default
, приведенной ниже.
default(тип)
Эта форма оператора default
пригодна для всех аргументов типа, будь то типы значений или ссылочные типы.
Ниже приведен короткий пример, демонстрирующий данную форму оператора
default
.
// Продемонстрировать форму оператора default.
using System;
class MyClass {
//...
}
// Получить значение, присваиваемое параметру типа Т по умолчанию,
class Test {
public T obj;
public Test() {
// Следующий оператор годится только для ссылочных типов.
// obj = null; //не годится
// Следующий оператор годится только для типов значений.
// obj = 0; // не годится
// А этот оператор годится как для ссылочных типов,
// так и для типов значений,
obj = default(T); // Годится!
Интервал:
Закладка: