实际上,我试图实现一个链表作为一个大学项目。在第一步中,我编写了一个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;
当你有很多不同的泛型参数时,这很方便。