实际上,我试图将链表列为大学项目。
在第一步中,我编写了一个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)
好的,你想创建一个异构列表,它可以包含任何类型(和任何混合)的对象。 这意味着仿制药已经淘汰。
<强> 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
if {{1}是空的。
如果你想传入空对象并且能够指定一个类型(这有点奇怪,但仍然......)那么你可以有另一种方法,你不必指定一个对象所有,只是一种类型:
sValue
我质疑这种效用。
<强> public Element(Element sPrevious, Element sNext, Type type)
{
Previous = sPrevious;
Next = sNext;
Value = null;
Type = type;
}
强>
您缺少的另一条信息是,您可以使用typeof()
运算符从类型名称中获取Type
对象,例如:
typeof()
我不确定你是如何实际使用价值和类型的;我想你将不得不进行大量的&#34; check-type-and-cast&#34;代码周围,我不确定是个好主意......
答案 1 :(得分:0)
尝试使用泛型而不是手动转换和类型存储。
(并且,courser,List和LinkedList已在.Net框架中实现)
答案 2 :(得分: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;
考虑使用方法创建一些Factory,这将创建对象。然后,您可以省略指定通用参数,它们将从方法的使用中推断出(或推断)。例如:
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;
当你有许多不同的通用参数时,这会派上用场。