public class linkedListNode
{
public object Value { get; private set; }
public linkedListNode(object value)
{
Value = value;
}
public linkedListNode Prev { get; internal set; }
public linkedListNode Next { get; internal set; }
}
public class linkedList : IEnumerable
{
public linkedListNode First { get; private set; }
public linkedListNode Last { get; private set; }
//在链表尾部添加一个新元素
public linkedListNode AddLast(object node)
{
var newNode = new linkedListNode(node);
if (First == null)
{
First = newNode;
Last = First;
}
else
{
linkedListNode previous = Last;
Last.Next = newNode;
Last = newNode;
Last.Prev = previous;
}
return newNode;
}
//实现GetEnumerator()方法
public IEnumerator GetEnumerator()
{
linkedListNode current = First;
while (current != null)
{
//使用yield语句创建一个枚举器类型
yield return current.Value;
current = current.Next;
}
}
}
var list1 = new linkedList();
list1.AddLast(2);
list1.AddLast(3);
list1.AddLast("4");
foreach (var i in list1)
{
Console.WriteLine(i);
}
使用泛型定义上述类
public class linkedListNode
{
public linkedListNode(T value)
{
Value = value;
}
public linkedListNode Next { get; internal set; }
public linkedListNode Prev { get; internal set; }
public T Value { get; private set; }
}
public class linkedList : IEnumerable
{
public linkedListNode First { get; private set; }
public linkedListNode Last { get; private set; }
public linkedListNode AddLast(T node)
{
var newNode = new linkedListNode(node);
if (First == null)
{
First = newNode;
Last = First;
}
else
{
linkedListNode previous = Last;
Last.Next = newNode;
Last = newNode;
Last.Prev = previous;
}
return newNode;
}
public IEnumerator GetEnumerator()
{
linkedListNode current = First;
while (current != null)
{
yield return current.Value;
current = current.Next;
}
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
var list2 = new linkedList();
list2.AddLast("java");
list2.AddLast("c#");
list2.AddLast("python");
foreach (string i in list2)
{
Console.WriteLine(i);
}
泛型类功能
在创建泛型类时,可以为泛型类型指定默认值、约束、继承和静态成员等。
创建如下一个简单泛型类 ,用于从队列中读写文档。
public class documentManager
{
private readonly Queue documentQueue = new Queue();
public bool IsdocumentAvailable => documentQueue.Count > 0;
public void Adddocument(T doc)
{
lock (this)
{
documentQueue.Enqueue(doc);
}
}
}
//定义一个简单的接口
public interface Idocument
{
string Title { get; set; }
string Content { get; set; }
}
//实现该接口
public class document : Idocument
{
public document(string title, string content)
{
this.Title = title;
this.Content = content;
}
public string Content { get; set; }
public string Title { get; set; }
}
泛型类型默认值
在上述类documentManager中添加如下方法:
public T Getdocument()
{
//default将泛型类型的值初始化为null或者0,取决于泛型类型是引用类型还是值类型。
T doc = default(T);
lock (this)
{
doc = documentQueue.Dequeue();
}
return doc;
}
public abstract class Calc
{
public abstract T Add(T x, T y);
public abstract T Sub(T x, T y);
}
public class IntCalc : Calc
{
public override int Add(int x, int y) => x + y;
public override int Sub(int x, int y) => x - y;
}
还可以创建一个部分的特殊操作,如下:
public class Query { }
public class StringQuery : Query { }
public class Shape
{
public double Width { get; set; }
public double Height { get; set; }
//重写Object的ToString方法
public override string ToString() => $"Width:{Width},Height:{Height}";
}
//定义子类Rectangle
public class Rectangle : Shape { }
泛型接口的协变
如果泛型类型使用out关键字标注,该泛型接口就是协变的。
public interface IIndex
{
//定义一个索引器
T this[int index] { get; }
int Count { get; }
}
public class RectangleCollection : IIndex
{
private Rectangle[] data = new Rectangle[3] {
new Rectangle{Height=2,Width=5},
new Rectangle{ Height=3, Width=7},
new Rectangle{ Height=4.5, Width=2.9}
};
public int Count => data.Length;
public Rectangle this[int index]
{
get
{
if (index < 0 || index > data.Length)
{
throw new ArgumentOutOfRangeException("index");
}
return data[index];
}
}
}
//静态类不能被实例化
public static class Algorithms
{
public static decimal Accumulate(IEnumerable source)
where TAccount : IAccount
{
decimal sum = 0;
foreach (TAccount a in source)
{
sum += a.Balance;
}
return sum;
}
}
调用上述方法的代码:
var accounts = new List {
new Account("书籍",234),
new Account("文具",56),
new Account("手机",2300)
};
//decimal amount = Algorithms.Accumulate(accounts);
//编译器会从方法的参数类型中自动推断出泛型类型参数,可以简化为下述代码进行调用
decimal amount = Algorithms.Accumulate(accounts);
var accounts = new List {
new Account("书籍",234),
new Account("文具",56),
new Account("手机",2300)
};
decimal amount = Algorithms.Accumulate(
accounts, //传入的参数1
(item, sum) => sum += item.Balance //传入的参数2
);