2013-03-24 1 views
1

На самом деле, я пытаюсь реализовать связанный список как университетский проект. На первом этапе я запрограммировал класс ListElementBase и суровые классы ListElement, наследующие от этого класса для каждого типа данных.Связанный список с объектной стоимостью и типом данных

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

Как-то вроде этого:

private struct Element 
{ 
    public Element Previous; 
    public Element Next; 

    public object Value; 
    public ValueType Type; 

    public Element(Element sPrevious, Element sNext, object sValue, ValueType sType) 
    { 
     Previous = sPrevious; 
     Next = sNext; 
     Value = sValue; 
     Type = sType; 
    } 
} 

Но я не понимаю, как обращаться с DATATYPE. Я не могу создать экземпляр для DataType или вызвать конструктор вроде new Element(..., ..., ..., string).

Я полностью на неправильном пути?

+0

Нет, вы не на неправильном пути , Похоже, вы идете в правильном направлении. –

+1

Вы хотите, чтобы ваш связанный список мог хранить объекты разных типов, или каждый связанный список будет содержать только один тип объекта? –

+0

Я хочу реализовать общий список, который может содержать любой тип данных в том же списке. –

ответ

1

Хорошо, вы хотите создать гетерогенный список, который может содержать любой тип (и любой микс) объектов. Это означает, что дженерики отсутствуют.

object.GetType()

Если вы хотите, чтобы автоматически определить тип объекта, переданного в Element конструктора, можно сделать так:

public Element(Element sPrevious, Element sNext, object sValue) 
{ 
    Previous = sPrevious; 
    Next = sNext; 
    Value = sValue; 
    Type = (sValue != null) ? sValue.GetType() : typeof(object); 
} 

Другими словами, вы можете избежать прохождения параметр типа полностью, и просто спросите об этом объект.

Это работает, потому что все объекты производятся от System.Object, и существует способ System.Object.GetType().

Однако не будет работать, еслиsValue равна нулю, поэтому я проверяю на нуль и установите тип в object если sValue является недействительным.

Если вы хотите передать нулевые объекты и сохранить возможность указать тип (что было бы немного странно, но все же ...), то у вас может быть другой метод, в котором вы вообще не укажете объект , только один тип:

public Element(Element sPrevious, Element sNext, Type type) 
{ 
    Previous = sPrevious; 
    Next = sNext; 
    Value = null; 
    Type = type; 
} 

Я сомневаюсь в полезности этого.

typeof()

Другая часть информации вы не хватает в том, что вы можете получить Type объект из имени типа с помощью оператора typeof(), например:

Type t1 = typeof(string); 
Type t2 = typeof(int); 

Я m не уверен, как вы собираетесь использовать значение и тип; Я думаю, вам придется иметь много кода «check-type-and-cast», и я не уверен, что это хорошая идея ...

0

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

(И, Courser, Перечень и LinkedList уже реализованы в рамках .Net)

+0

Я знаю Списки уже реализованы в .Net. Как уже упоминалось, в настоящее время я изучаю информатику и стараюсь реализовать связанный список самостоятельно, только для эффекта обучения, независимо от того, полезен он или нет. –

0

Самый простой и наивная реализация для элемента двойного связанного списка с использованием дженериков, как в следующем:

public class Element<T> 
{ 
    public Element<T> Prev { get; set; } 
    public Element<T> Next { get; set; } 
    public T Value { get; set; } 

    public Element(T value, Element<T> prev, Element<T> next) 
    { 
     Prev = prev; 
     Next = next; 
     Value = value; 
    } 
} 

T - это параметр типа, который вы можете указать, что хотите. Теперь вы можете опустить ValueType, потому что теперь вы можете получить тип значения, например, element.Value.GetType() вне класса и typeof(T) внутри класса.

Чтобы можно создать список используйте следующий фрагмент кода:

var now = DateTime.Now; 
var first = new Element<DateTime>(now, null, null); 

var second = new Element<DateTime>(now.AddDays(1), first, null); 
first.Next = second; 

var third = new Element<DateTime>(now.AddDays(2), second, null); 
second.Next = third; 

рассмотреть вопрос о создании какой-то завод с методами, которые будут создавать вам объекты. Затем вы можете опустить задание общих параметров, они будут выведены (или inferred) из использования метода. Например:

public class Factory 
{ 
    public static Element<T> Create<T>(T value, Element<T> prev, Element<T> next) 
    { 
     return new Element<T> (value, prev, next); 
    } 
} 

теперь вы можете создавать такие элементы, как:

var now = DateTime.Now; 

var first = Factory.Create(now, null, null); 

var second = Factory.Create(now.AddDays(1), first, null); 
first.Next = second; 

var third = Factory.Create(now.AddDays(2), second, null); 
second.Next = third; 

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

+0

. NET. LinkedList 'является двойной связью. – antonijn

+0

@antonijn да, конечно. И в чем смысл? :) –

+0

Ну, вы только что продемонстрировали реализацию для односвязного списка, тогда как вопрос OP показывает, что он/она хочет иметь двойную связь. – antonijn

Смежные вопросы