具有对象值和数据类型的链表

本文关键字:数据类型 链表 对象 | 更新日期: 2023-09-27 18:05:36

实际上,我试图实现一个链表作为一个大学项目。在第一步中,我编写了一个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)那样调用构造函数。

我完全走错路了吗?

具有对象值和数据类型的链表

好的,您想要创建一个异构列表,它可以包含任何类型(和任何混合)的对象。这意味着泛型已经过时了。

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为空,则将不工作,这就是为什么我检查null并将类型设置为object,如果sValue为空。

如果你想传入空对象并保持指定类型的能力(这可能有点奇怪,但仍然…),那么你可以有另一个方法,你根本不指定对象,只是一个类型:

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

但我怀疑这种做法的效用。

typeof()

您遗漏的另一条信息是,您可以通过使用typeof()操作符从类型名称中获得Type对象,例如:
Type t1 = typeof(string);
Type t2 = typeof(int);

我不确定你将如何使用值和类型;我猜你将不得不有很多"检查类型和转换"的代码,我不确定这是一个好主意…

尝试使用泛型来代替手动强制转换和类型存储。

(当然,List和LinkedList已经在。net框架中实现了)

使用泛型实现双链表中元素的最简单和最朴素的方法如下:

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;

考虑创建一些带有方法的工厂,这些方法将为你创建对象。然后您可以省略指定泛型参数,它们将从方法的使用中推断出来(或推断出)。例如:

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;

当你有很多不同的泛型参数时,这很方便。