Эндрю Троелсен - ЯЗЫК ПРОГРАММИРОВАНИЯ С# 2005 И ПЛАТФОРМА .NET 2.0. 3-е издание
- Название:ЯЗЫК ПРОГРАММИРОВАНИЯ С# 2005 И ПЛАТФОРМА .NET 2.0. 3-е издание
- Автор:
- Жанр:
- Издательство:Издательский дом Вильямс
- Год:2007
- Город:Москва • Санкт-Петербург • Киев
- ISBN:ISBN 5-8459-1124-9
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Эндрю Троелсен - ЯЗЫК ПРОГРАММИРОВАНИЯ С# 2005 И ПЛАТФОРМА .NET 2.0. 3-е издание краткое содержание
В этой книге содержится описание базовых принципов функционирования платформы .NET, системы типов .NET и различных инструментальных средств разработки, используемых при создании приложений .NET. Представлены базовые возможности языка программирования C# 2005, включая новые синтаксические конструкции, появившиеся с выходом .NET 2.0, а также синтаксис и семантика языка CIL. В книге рассматривается формат сборок .NET, библиотеки базовых классов .NET. файловый ввод-вывод, возможности удаленного доступа, конструкция приложений Windows Forms, доступ к базам данных с помощью ADO.NET, создание Web-приложений ASP.NET и Web-служб XML. Книга содержит множество примеров программного кода, призванного помочь читателю в освоении предлагаемого материала. Программный код примеров можно загрузить с Web-сайта издательства.
ЯЗЫК ПРОГРАММИРОВАНИЯ С# 2005 И ПЛАТФОРМА .NET 2.0. 3-е издание - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
public bool Contains( SportsCaritem);
public void CopyTo( SportsCar[] array);
public int FindIndex(System.Predicate‹ SportsCar› match);
public SportsCar FindLast(System.Predicate‹ SportsCar› match);
public bool Remove( SportsCaritem);
public int RemoveAll(System.Predicate‹ SportsCar› match);
publiс SportsCar[] ToArray();
public bool TrueForAll(System.Predicate‹ SportsCar› match);
public SportsCarthis[int index] { get; set; }
…
}
}
Конечно, когда вы создаете обобщенный List‹T›, нельзя сказать, что компилятор буквально создает совершенно новую реализацию типа List‹T›. Он обращается только к тем членам обобщенного типа, которые вы вызываете фактически. Чтобы пояснить это, предположим, что вы используете List‹T› для объектов SportsCar так.
static void Main(string[] args) {
// Проверка List, содержащего объекты SportsCars.
List‹SportsCar› myCars = new List‹SportsCar›();
myCars.Add(new SportsCar());
Console.WriteLine("Your List contains {0}", myCars.Count);
}
Если с помощью ildasm.exe проверить генерируемый CIL-код, обнаружатся следующие подстановки.
.method private hidebysig static void Main(string[] args) cil managed {
.entrypoint
.maxstack 2
.locals init ([0] class [mscorlib] System.Collections.Generic.'List`1'‹class SportsCar›myCars)
newobj instance void class [mscorlib]System.Collections.Generic.'List`1'‹class SportsCar›::.ctor()
stloc.0
ldloc.0
newobj instance void CollectionGenerics.SportsCar::.ctor()
callvirt instance void class [mscorlib]System.Collections.Generic.'List`1'‹class SportsCar›::Add(!0)
nop
ldstr "Your List contains {0} item(s)."
ldloc.0
callvirt instance int32 class [mscorlib] System.Collections.Generic.'List`1' ‹class SportsCar›::get_Count()
box [mscorlib] System.Int32
call void [mscorlib]System.Console::WriteLine(string, object)
nop
ret
}
Теперь, после изучения процесса использования обобщенных типов из библиотек базовых классов, в оставшейся части главы мы рассмотрим вопросы создания обобщенных методов, типов и коллекций.
Создание обобщенных методов
Чтобы научиться интегрировать обобщения в проекты, мы начнем с простого примера обычной подпрограммы свопинга. Целью этого примера является построение метода обмена, который сможет работать c любыми типами данных (характеризуемыми значениями или ссылками), используя для этого один параметр типа. В силу самой природы алгоритмов свопинга входные параметры будут посылаться по ссылке (с помощью ключевого слова C# ref). Вот соответствующая полная реализация.
// Этот метод переставляет любые два элемента,
// определенные параметром типа ‹Т›.
static void Swap‹T›(ref T a, ref Т b) {
Console.WriteLine ("Методу Swap () передано {0}", typeof(T));
Т temp;
temp = а;
а = b;
b = temp;
}
Обратите внимание на то, что обобщенный метод определяется с помощью указания параметра типа, размещаемого после имени метода, но перед списком параметров. Здесь вы заявляете, что метод Swap() может работать с любыми двумя параметрами типа ‹Т›. Просто для информации вы выводите имя типа соответствующего заменителя на консоль с помощью оператора C# typeof(). Теперь рассмотрите следующий метод Main(), в котором происходит обмен между целочисленными и строковыми типами.
static void Main(string[] args) {
Console.WriteLine("***** Забавы с обобщениями *****\n") ;
// Обмен между двумя целыми.
int а = 10, b = 90;
Console.WriteLine("До обмена: {0}, {l}", а, b);
Swap‹int›(ref a, ref b);
Console.WriteLine("После обмена: {0}, {1}", а, b);
Console.WriteLine();
// Обмен между двумя строками.
string s1 = "Hello", s2 = "There";
Console.WriteLine("До обмена: {0} {1}!", s1, s2);
Swap‹string›(ref s1, ref s2);
Console.WriteLine("После обмена: {0} {1}!", s1, s2);
Console.ReadLine();
}
Пропуск параметров типа
При вызове обобщенных методов, подобных Swap‹T›, у ваc есть возможность не указывать параметр типа, но только в том случае, когда обобщенный метод требует указания аргументов, поскольку тогда компилятор может "выяснить" тип этих аргументов на основе вводимых параметров. Например, можно переставить два типа System.Boolean так.
// Компилятор будет предполагать System.Boolean.
bool b1 = true, b2 = false;
Console.WriteLine("До обмена: {0}, {1}", b1, b2);
Swap(ref b1, ref b2);
Console.WriteLine("После обмена: {0}, {1}", b1, b2);
Но если, например, у вас есть обобщённый метод с именем DisplayBaseClass‹T›, не имеющий входных параметров, как показано ниже:
static void DisplayBaseClass‹T›() {
Console.WriteLine("Базовым классом {0} является: {1}.", typeof(T), typeof(Т).BaseType);
}
то при вызове этого метода вы должны указать параметр типа.
static void Main(string[] args) {
…
// Если метод не имеет параметров,
// необходимо указать параметр типа.
DisplayBaseClass‹int›();
DisplayBaseClass‹string›();
// Ошибка компиляции!
// Нет параметров? Тогда должен быть заполнитель!
DisplayBaseClass();
…
}

Рис. 10.1. Обобщенные методы в действии
В данном случае обобщенные методы Swap‹T› и DisplayBaseClass‹T› были определены в рамках объекта приложения (т.е. в рамках типа, определяющего метод Main()). Если вы предпочтете определить эти члены в новом типе класса (MyHelperClass), то должны записать следующее.
public class MyHelperClass {
public static void Swap‹T›(ref T a, ref T b) {
Console.WriteLine("Методу Swap() передано {0}", typeof(T));
T temp;
temp = a;
a = b;
b = temp;
}
public static void DisplayBaseClass‹T›() {
Console.WriteLine("Базовым классом {0} является: {1}.", typeof(T), typeof(T).BaseType);
}
}
Обратите внимание на то, что тип MyHelperClass сам по себе не является обобщенным, но определяет два обобщенных метода. Так или иначе, теперь, когда методы Swap‹T› и DisplayBaseClass‹T› находятся в контексте нового типа класса, при вызове их членов придется указать имя типа.
MyHelperClass.Swap‹int›(ref a, ref b);
Наконец, обобщенные методы не обязаны быть статическими. Если бы Swap‹T› и DisplayBaseClass‹T› были методами уровня экземпляра, нужно было бы просто создать экземпляр MyHelperClass и вызвать их из объектной переменной.
MyHelperClass с = new MyHelperClass();
c.Swap‹int›(ref a, ref b);
Создание обобщенных структур (и классов)
Теперь, когда вы понимаете, как определять и вызывать обобщенные методы, давайте рассмотрим построение обобщенных структур (процедура построения обобщенных классов оказывается аналогичной). Предположим, что мы построили гибкую структуру Point, поддерживающую один параметр типа, который представляет единицу хранения координат (х, у) . Вызывающая сторона может создавать типы Point‹T› так.
Читать дальшеИнтервал:
Закладка: