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

Преобразования типов

Читайте также:
  1. А. Атипові м'язові волокна целомічного типу
  2. Анализ типовых схем базирования.
  3. влияние ступеней специализации и типов производства на минимально допустимые и оптимальные размеры производственных мощностей машиностроительных предприятий
  4. Внутренний мир архетипов
  5. Выбор типового выпрямительного устройства
  6. Генетических типов
  7. Глава 14. Россия в конце XVII - первой четверти XVIII в. Петровские преобразования.

С помощью метода ConvertAll() класса List<T> все элементы коллекции могут быть преобразованы в другой тип. Метод ConvertAll() использует делегат Converter, определенный следующим образом:

public sealed delegate TOutput Converter<TInput, TOutput>(TInput from);

При преобразовании используются обобщенные типы TInput и TOutput. ТInput — это аргумент метода делегата, a TOutput — возвращаемый тип.

В следующем примере все элементы типа Student должны быть преобразованы в тип Person. В то время как тип Student включает полное имя и номер группы, тип Person включает имя (firstname) и фамилию (lastname). При таком преобразовании номер группы может быть проигнорирована, но имя нужно преобразовать в firstname и lastname:

 

class Person

{

private string firstname;

private string lastname;

public Person(string firstname, string lastname)

{

this.firstname = firstname;

this.lastname = lastname;

}

public override string ToString()

{

return firstname+ " "+lastname;

}

}

 

Преобразование выполняется вызовом метода students.ConvertAll<Person>. Параметр этого метода определен, как анонимный метод с аргументом типа Student, возвращающий значение типа Person. В реализации анонимного метода создается и возвращается новый объект Person. Свойство FullName объекта Student преобразуется в firstname и
lastname:

 

List<Person> persons = students.ConvertAll<Person>(delegate(Student st)

{int ixSeparator = st.FullName.LastIndexOf(" ") + 1;

string firstname = st.FullName.Substring(ixSeparator,

st.FullName.Length - ixSeparator);

string lastname = st.FullName.Substring(0,

ixSeparator - 1);

return new Person(firstname, lastname);};

 

В результате такого преобразования получается список конвертированных объектов Person — то есть List<Person> (рис. 7.5).

 

Рис. 7.5. Результаты преобразования класса Student в класс Person

Использование класса Queue<T>

Класс Queue<T> обладает той же функциональностью, что и класс Queue — то есть это просто обобщенная версия очереди. Элементы обрабатываются по алгоритму «первым пришел — первым обслужен» (FIFO).

В качестве примера применения класса Queue<T> рассмотрим приложение управления документацией. Один поток управления будет добавлять документы в очередь, а второй — извлекать из очереди и обрабатывать.

Элементы, сохраняемые в очереди, будут относиться к типу Document. Класс Document состоит из заголовка и содержимого:

 

public class Document

{

private string title;

private string content;

public string Title

{

get { return title; }

}

public string Content

{

get { return content; }

}

public Document(string title, string content)

{

this.title = title;

this.content = content;

}

}

 

Класс DocumentManager — надстройка над Queue<T>. Класс
DocumentManager определяет, как обрабатываются документы: добавляются в очередь методом AddDocument() и извлекаются методом
GetDocument().

Внутри метода AddDocument() документ добавляется в конец очереди с помощью метода Enqueue(). Первый документ из очереди читается методом Dequeue() внутри GetDocument(). Поскольку к DocumentManager могут иметь одновременный доступ несколько потоков параллельно, доступ к очереди блокируется оператором lock.

IsDocumentAvailable — свойство булевского типа, доступное только для чтения; оно возвращает true, если в очереди есть документы и false — в противном случае:

 

public class DocumentManager

{

private readonly Queue<Document> documentQueue = new Queue<Document>();

public void AddDocument(Document doc)

{

lock (this)

{

documentQueue.Enqueue(doc);

}

}

public Document GetDocument()

{

Document doc = null;

lock (this)

{

doc = documentQueue.Dequeue();

}

return doc;

}

public bool IsDocumentAvailable

{

get

{

return documentQueue.Count > 0;

}

}

}

 

Класс ProcessDocuments обрабатывает документы из очереди в отдельном потоке. Единственный его метод, который доступен извне — это Start(). В теле метода Start() создается экземпляр нового потока. Объект
ProcessDocuments создается для запуска потока, а метод Run() определен как стартовый метод потока. ThreadStart — делегат, который ссылается на метод, подлежащий запуску в потоке. После создания объекта Thread поток запускается вызовом Thread.Start().

Внутри метода Run() класса ProcessDocuments определен бесконечный цикл. В этом цикле свойство IsDocumentAvailable используется для проверки наличия документа в очереди. Если в очереди есть документ, то документ извлекается DocumentManager и обрабатывается. В данном случае вся обработка сводится к отображению информации на консоли. В реальном приложении документ может быть записан в файл, сохранен в базе данных либо отправлен по сети.

 

public class ProcessDocument

{

private DocumentManager documentManager;

public static void Start(DocumentManager dm)

{

new Thread(new ProcessDocument(dm).Run).Start();

}

protected ProcessDocument(DocumentManager dm)

{

documentManager = dm;

}

protected void Run()

{

while (true)

{

if (documentManager.IsDocumentAvailable)

{

Document doc = documentManager.GetDocument();

Console.WriteLine("Обработка документа {0}", doc.Title);

}

Thread.Sleep(new Random().Next(20));

}

}

}

 

В методе Main() приложения создается объект DocumentManager, создается 100 документов с номерами от 0 до 99 и запускается поток обработки документов. Затем создается 10 документов с номерами от 100 до 110, и все они добавляются в DocumentManager. В реальном приложении документы могут поступать от Web-службы.

 

class Program

{

static void Main(string[] args)

{

DocumentManager dm = new DocumentManager();

for (int i = 0; i < 100; i++)

{

Document doc = new Document("Документ " + i.ToString(), "Содержание " + i.ToString());

dm.AddDocument(doc);

Thread.Sleep(new Random().Next(10));

}

Console.WriteLine("\nФормирование документов завершено\n");

ProcessDocument.Start(dm);

for (int i = 101; i < 110; i++)

{

Document doc = new Document("Документ "+i.ToString(), "Содержание "+i.ToString());

dm.AddDocument(doc);

Console.WriteLine("Добавленный документ {0}", doc.Title);

Thread.Sleep(new Random().Next(20));

}

}

}

 

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

 

а) начало вывода б) окончание вывода

Рис. 7.6. Добавление и извлечение из очереди документов


Дата добавления: 2015-07-07; просмотров: 130 | Нарушение авторских прав


Читайте в этой же книге: Повторное использование двоичного кода | Обзор обобщенных коллекций | Поиск элементов | Обобщенные методы | Обобщенные делегаты |
<== предыдущая страница | следующая страница ==>
Сортировка| Создание пользовательских обобщенных классов

mybiblioteka.su - 2015-2024 год. (0.013 сек.)