泛型节点声明

时间:2011-10-27 15:37:34

标签: c# generics nested-generics

Microsoft将此作为学习泛型的冒泡排序示例。直到我到达第76和77行才有意义。这些声明怎么可能? Node是一个类。你不必用新的实例化吗? 你会如何优化排序?哪一部分是通用的,哪些是非通用的?

1   public class GenericList<T> : System.Collections.Generic.IEnumerable<T>
2       {
3           protected Node head;
4           protected Node current = null;
5   
6           // Nested class is also generic on T
7           protected class Node
8           {
9               public Node next;
10              private T data;  //T as private member datatype
11   
12              public Node(T t)  //T used in non-generic constructor
13              {
14                  next = null;
15                  data = t;
16              }
17  
18              public Node Next
19              {
20                  get { return next; }
21                  set { next = value; }
22              }
23  
24              public T Data  //T as return type of property
25              {
26                  get { return data; }
27                  set { data = value; }
28              }
29          }
30  
31          public GenericList()  //constructor
32          {
33              head = null;
34          }
35  
36          public void AddHead(T t)  //T as method parameter type
37          {
38              Node n = new Node(t);
39              n.Next = head;
40              head = n;
41          }
42  
43          // Implementation of the iterator
44          public System.Collections.Generic.IEnumerator<T> GetEnumerator()
45          {
46              Node current = head;
47              while (current != null)
48              {
49                  yield return current.Data;
50                  current = current.Next;
51                  
52              }
53          }
54  
55          System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
56          {
57              return GetEnumerator();
58          }
59      }
60  
61      public class SortedList<T> : GenericList<T> where T : System.IComparable<T>
62      {
63          // A simple, unoptimized sort algorithm that 
64          // orders list elements from lowest to highest:
65  
66          public void BubbleSort()
67          {
68              if (null == head || null == head.Next)
69              {
70                  return;
71              }
72              bool swapped;
73  
74              do
75              {
76                  Node previous = null;
77                  Node current = head;
78  
79                  
80                  //Console.WriteLine(previous.GetType());
81                  //Console.ReadLine();
82  
83                  swapped = false;
84                  
85                   
86                  //Debug.WriteLine(p);
87                  //Debug.WriteLine("Testing " + current.ToString());
88  
89                  while (current.next != null)
90                  {
91                      //  Because we need to call this method, the SortedList
92                      //  class is constrained on IEnumerable<T>
93                      if (current.Data.CompareTo(current.next.Data) > 0)
94                      {
95                          Node tmp = current.next;
96                          current.next = current.next.next;
97                          tmp.next = current;
98  
99                          if (previous == null)
100                         {
101                             head = tmp;
102                         }
103                         else
104                         {
105                             previous.next = tmp;
106                         }
107                         previous = tmp;
108                         swapped = true;
109                     }
110                     else
111                     {
112                         previous = current;
113                         current = current.next;
114                     }
115                 }
116             } while (swapped);
117         }
118     }

4 个答案:

答案 0 :(得分:2)

C#中的class类型可以使用null初始化,也可以使用与声明兼容的类型初始化。第76和77行看起来像这样

Node previous = null;
Node current = head;

此处值null是合法的。它基本上说“我没有价值”。对head的分配也是合法的,因为head也属于Node类型。结果是两个引用headcurrent引用相同的Node对象值。通过其中一个引用修改Node实例将对另一个进行修改。

答案 1 :(得分:0)

您分别将previousnext分配给nullhead。这是一个任务操作,就像任何其他操作一样。除非您实际创建对象的新实例,否则不需要使用new。

通用部分是指T的任何内容。它是在实例化类时提供的泛型类型。一个很好的例子是List<T>,它创建了T类型的对象列表。您可以将此实例设置为List<string>以获取字符串列表,List<int>获取整数列表等。

答案 2 :(得分:0)

引用可以指向实例,也可以只是null

您可以为其他参考分配参考:

Foo f1 = new Foo();
Foo f2 = f1;
Foo f3 = null;

答案 3 :(得分:0)

该代码中的第76行和第77行没有实例化对象。如你所说,Node是一个类。 .NET中的类始终是引用类型,这意味着:

  1. 引用类型变量的值是对象的引用(或者什么都没有)。
  2. 可以为引用类型的变量赋值null,这意味着变量不引用任何内容。
  3. 将引用类型的一个变量分配给引用类型的另一个变量会复制引用,而不是对象。