КАТЕГОРИИ:
АстрономияБиологияГеографияДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРиторикаСоциологияСпортСтроительствоТехнологияФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника
|
Обобщенные типы и наследованиеОбобщенный тип, как и всякий другой, может быть производным от других типов. При использовании обобщенного типа с указанием аргументов-типов в CLR определяется новый объект-тип, производный от того же типа, что и обобщенный тип. Например, List<T> является производным от Object, поэтому List<String> и List<Guid> тоже производные от Object. Аналогично, DictionaryStringKey<TValue> — производный от Dictionary<String, TValue>, поэтому DictionaryStringKey<Guid> также производный от Dictionary<String, Guid>. Понимание того, что определение аргументов-типов не имеет ничего общего с иерархиями наследования, позволяет разобраться, какие приведения типов допустимы, а какие нет. Например, пусть класс Node связного списка определяется следующим образом.
internal sealed class Node<T> { public T m_data; public Node<T> m_next;
public Node(T data) : this(data, null) { }
public Node(T data, Node<T> next) { m_data = data; m_next = next; }
public override String ToString() { return m_data.ToString() + ((m_next != null) ? m_next.ToStringO : null); } }
Тогда код для создания связного списка будет примерно таким:
private static void SameDataLinkedList() { Node<Char> head = new Node<Char>('C'); head = new Node<Char>('B', head); head = new Node<Char>('A', head); Console.WriteLine(head.ToString()); }
В приведенном выше классе Node поле m_next должно ссылаться на другой узел, поле m_data которого содержит тот же тип данных. Это значит, что узлы связного списка должны иметь одинаковый (или производный) тип данных. Например, нельзя использовать класс Node для создания связного списка, в котором тип данных одного элемента — Char, другого — DateTime, а третьего — String. Однако, определив необобщенный базовый класс Node, а затем — обобщенный класс TypedNode (используя класс Node как базовый), можно создать связный список с произвольным типом данных у каждого узла. Приведу определения новых классов.
internal class Node { protected Node m_next;
public Node(Node next) { m_next = next; } }
internal sealed class TypedNode<T> : Node { public T m_data;
public TypedNode(T data) : this(data, null) {}
public TypedNode(T data, Node next) : base(next) { m_data = data; }
public override String ToString() { return m_data.ToString() + ((m_next != null) ? m_next.ToString() : null); } }
Теперь можно написать код для создания связного списка с разными типами данных у разных узлов. Код будет примерно таким.
private static void DifferentDataLinkedList() { Node head = new TypedNode<Char>('.'); head = new TypedNode<DateTime>(DateTime.Now, head); head = new TypedNode<String>("Today is ", head); Console.WriteLine(head.ToString()); }
|