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).

我完全走错了路吗?

4

3 回答 3

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()

但是,如果为 null,它将不起作用sValue这就是为什么我检查 null 并将类型设置为objectif sValueis null。

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

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);

我不确定您将如何实际使用值和类型;我想你将不得不有很多“检查类型和转换”代码,我不确定这是一个好主意......

于 2013-03-24T11:23:39.847 回答
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;

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

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;

当您有许多不同的泛型参数时,这会派上用场。

于 2013-03-24T10:20:52.707 回答
0

尝试使用泛型而不是手动转换和类型存储。

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

于 2013-03-24T10:09:53.470 回答