在发布我的问题之前,我想告诉你我以前没有.Net技术的经验,并且最近开始学习C#(和WPF)。我的公司正在寻求转向.Net技术,我是我团队中唯一一个学习它的人,所以除了你们之外没有人讨论或询问过什么。因此,如果我的问题太愚蠢或最基本,请耐心等待。
我试图创建一个通用的链表类,以允许创建不同类型的链表。我编写了以下代码,并希望就是否正确编写此代码提出建议。任何以任何方式改进代码的建议都是受欢迎的。
主程序
class Program
{
static void Main(string[] args)
{
GenLinkedList<string> list = new GenLinkedList<string>("abc");
list.AddtoList("def");
int i = 0;
string[] arr = new string[10];
list.LinkedList.CopyTo(arr,0);
for (i = 0; i < list.LinkedList.Count; i++)
{
Console.WriteLine(arr[i]);
}
GenLinkedList<int> listInt = new GenLinkedList<int>(1);
listInt.AddtoList(2);
i = 0;
int[] arrInt = new int[10];
listInt.LinkedList.CopyTo(arrInt, 0);
for (i = 0; i < listInt.LinkedList.Count; i++)
{
Console.WriteLine(arrInt[i]);
}
}
}
班级GenLinkedList
public class GenLinkedList<T>
{
private LinkedList<T> _linkedlist;
public GenLinkedList(T a)
{
_linkedlist = new LinkedList<T>();
_linkedlist.AddLast(a);
}
public LinkedList<T> LinkedList
{
get
{
return _linkedlist;
}
}
public void AddtoList(T a)
{
LinkedList.AddLast(a);
}
}
答案 0 :(得分:7)
为什么不使用System.Collections.Generic.LinkedList<T>
?您已在GenLinkedList<T>
内部使用它,它已经是您的通用。
这是框架提供的通用双链表实现。请阅读:
如果您要创建通用链接列表作为练习,则不应基于现有通用链接列表的实现。你真的不会通过包装已经完全符合你需要的东西来学习任何东西。
答案 1 :(得分:3)
.NET框架中已存在通用链表实现:LinkedList<T>
。但你已经知道了;你的代码包装它。
好的,所以你知道。那么你为什么要把它包起来呢?您似乎实现的唯一功能是AddtoList
,LinkedList<T>
没有执行任何操作(毕竟,这只是LinkedList<T>.AddLast
周围的一个薄包装) 。这意味着您的GenLinkedList<T>
类 不提供链表的功能;它基本上是一个只添加的集合(可以很容易地使用List<T>
,Stack<T>
或Queue<T>
实现 - 真的是任何东西。
假设你做有充分的理由来包装LinkedList<T>
(例如,你计划在线上添加更多功能,实际上会利用{{1}的行为} 和/或 - 这是一个关键因素 - 你希望限制调用代码能够与列表交互的方式(例如,没有删除)),你真的不应该暴露你的LinkedList<T>
成员。包装器的目的就是:包装。你拿一个现有的类,基本上给它一种新的界面。通过直接暴露底层对象,可以削弱包装器。您可以绕过包装器中的任何其他限制/验证/逻辑。
因此,例如,如果您希望能够将列表复制到数组中,而不是这样做:
LinkedList<T>
您可以在list.LinkedList.CopyTo(arr,0);
课程中实施CopyTo
方法(可以简单地调用GenLinkedList<T>
)并使用该方法。
但我真的认为你应该问自己的第一个问题是你想要通过首先包装_linkedlist.CopyTo
来实现的目标。
答案 2 :(得分:1)
显而易见的问题是,为什么你不直接使用LinkedList<T>
,虽然看起来你正试图模仿一个单链表。
在这种情况下,您应该避免暴露底层的LinkedList<T>
实例,因为任何客户端都可以直接操作它。我还会实现IEnumerable<T>
,这将使你的列表可以被linq使用。
答案 3 :(得分:0)
我从http://msdn.microsoft.com/en-us/library/0x6a29h6.aspx得到了这个 对我很好。
namespace GenLinkedList
{
class Program
{
static void Main(string[] args)
{
GenericList<object> list = new GenericList<object>();
// Add items to list.
list.AddHead("some string here");
list.AddHead(DateTime.Today.ToLongDateString());
list.AddHead(13);
list.AddHead(13.005);
for (int x = 0; x < 10; x++)
{
list.AddHead(x);
}
// Enumerate list.
foreach (object i in list)
{
Console.WriteLine(i + " " + i.GetType());
}
Console.WriteLine("\nDone");
}
}
}
namespace GenLinkedList
{
// type parameter T in angle brackets
class GenericList<T>
{
// The nested class is also generic on T.
public class Node
{
private Node next;
// T as private member data type.
private T data;
// T used in non-generic constructor.
public Node(T t)
{
next = null;
data = t;
}
public Node Next
{
get { return next; }
set { next = value; }
}
public T Data
{
get { return data; }
set { data = value; }
}
}
private Node head;
// constructor
public GenericList()
{
head = null;
}
// T as method parameter type
public void AddHead(T t)
{
Node n = new Node(t);
n.Next = head;
head = n;
}
public IEnumerator<T> GetEnumerator()
{
Node current = head;
while (current != null)
{
yield return current.Data;
current = current.Next;
}
}
}
}