C#高级语法基础知识总结2——泛型
泛型
值类型存储在栈上,引用类型存储在堆上。
从值类型转换为引用类型称为装箱。如果方法需要把一个对象作为参数,同时传递一个值类型,装箱操作就会自动进行。另一方面,装箱的值类型可以使用拆箱操作转换为值类型,拆箱时,需要使用类型强制转换运算符。
ArrayList存储对象,Add()方法定义为需要把一个对象作为参数,所以要装箱一个整数类型。在读取ArrayList中的值时,要进行拆箱,把对象转换为整数类型。可以使用类型强制转换运算符把ArrayList集合的第一个元素赋予变量i1,在访问int类型的变量i2的foreach语句中,也要使用类型强制转换运算符。
var list = new ArrayList(); list.Add(44);//装箱操作 int i1 =(int)list[0];//拆箱操作,强制转换类 foreach (int i2 in list) { Console.WriteLine(i2); }
泛型类型List<T>
使用泛型类型List<T>,不再进行装箱和拆箱操作。
var list1 = new List<int>(); list1.Add(55);//非装箱, int i3 = list1[0];//非拆箱 foreach (int i4 in list1) { Console.WriteLine(i4); }
创建一个一般的、非泛型的简化链表类
非泛型简化链表
1 public class LinkedListNode 2 { 3 private object _value; 4 public object Value { get { return _value; } private set { _value = value; } } 5 public LinkedListNode(object value) 6 { 7 this.Value=value; 8 } 9 public LinkedListNode Next{get;internal set;} 10 public LinkedListNode Prev{get;internal set;} 11 } 12 13 public class LimkedList:IEnumerable 14 { 15 public LinkedListNode First { get; private set; } 16 public LinkedListNode Last { get; private set; } 17 public LinkedListNode AddLast(object node) 18 { 19 var newNode = new LinkedListNode(node); 20 if(First==null) 21 { 22 First = newNode; 23 newNode.Prev = Last; 24 Last = First; 25 } 26 else 27 { 28 LinkedListNode previous = Last; 29 Last.Next = newNode; 30 Last = newNode; 31 Last.Prev = previous; 32 } 33 return newNode; 34 } 35 36 public IEnumerator GetEnumerator() 37 { 38 LinkedListNode current = First; 39 while (current != null) 40 { 41 yield return current.Value; 42 current = current.Next; 43 } 44 } 45 }
创建链表的泛型版本
泛型版链表
1 public class LinkedListNode<T> 2 { 3 private T _value; 4 public T Value { get { return _value; } private set { _value = value; } } 5 public LinkedListNode(T value) 6 { 7 this.Value = value; 8 } 9 public LinkedListNode<T> Next { get; internal set; } 10 public LinkedListNode<T> Prev { get; internal set; } 11 } 12 13 public class LinkedList<T> : IEnumerable<T> 14 { 15 public LinkedListNode<T> First { get; private set; } 16 public LinkedListNode<T> Last { get; private set; } 17 public LinkedListNode<T> AddLast(T node) 18 { 19 var newNode = new LinkedListNode<T>(node); 20 if (First == null) 21 { 22 First = newNode; 23 newNode.Prev = Last; 24 Last = First; 25 } 26 else 27 { 28 LinkedListNode<T> previous = Last; 29 Last.Next = newNode; 30 Last = newNode; 31 Last.Prev = previous; 32 } 33 return newNode; 34 } 35 36 public IEnumerator<T> GetEnumerator() 37 { 38 LinkedListNode<T> current = First; 39 while (current != null) 40 { 41 yield return current.Value; 42 current = current.Next; 43 } 44 } 45 46 IEnumerator IEnumerable.GetEnumerator() 47 { 48 return GetEnumerator(); 49 } 50 }
泛型支持的约束
泛型支持的约束
1 public class DocumentManager<TDocument> 2 where TDocument:IDocument 3 { 4 private readonly Queue<TDocument> documentQueue = new Queue<TDocument>(); 5 public void AddDocument(TDocument doc) 6 { 7 lock (this) 8 { 9 documentQueue.Enqueue(doc); 10 } 11 } 12 13 public bool IsDocumentAvailable 14 { 15 get { return documentQueue.Count > 0; } 16 } 17 18 public TDocument GetDocument() 19 { 20 TDocument doc = default(TDocument); 21 lock (this) 22 { 23 doc = documentQueue.Dequeue(); 24 } 25 return doc; 26 } 27 28 public void DisplayAllDocuments() 29 { 30 foreach (TDocument doc in documentQueue) 31 { 32 Console.WriteLine(((IDocument)doc).Title); 33 } 34 } 35 } 36 37 public interface IDocument 38 { 39 string Title{get;set;} 40 string Content{get;set;} 41 } 42 43 public class Document : IDocument 44 { 45 public string Title { get; set; } 46 public string Content { get; set; } 47 48 public Document() 49 { } 50 51 public Document(string title, string content) 52 { 53 this.Title = title; 54 this.Content = content; 55 } 56 57 }
泛型接口
非泛型接口继承
1 public class Person : IComparable 2 { 3 public int CompareTo(object obj) 4 { 5 Person other = obj as Person; 6 return this.lastname.CompareTo(other.lastName); 7 } 8 }
泛型接口继承
1 public class Person : IComparable<Person> 2 { 3 public int CompareTo(Person other) 4 { 5 return this.lastname.CompareTo(other.lastName); 6 } 7 }
泛型结构,不可继承
泛型结构,不可继承
1 public struct Nullable<T> 2 where T : struct 3 { 4 private bool _hasValue; 5 public bool HasValue 6 { 7 get { return _hasValue; } 8 } 9 10 private T _value; 11 public T Value 12 { 13 get 14 { 15 if (!_hasValue) 16 { 17 throw new InvalidOperationException("无值"); 18 } 19 return _value; 20 } 21 } 22 23 public Nullable(T value) 24 { 25 this._hasValue = true; 26 this._value = value; 27 } 28 29 public static explicit operator T(Nullable<T> value) 30 { 31 return value.Value; 32 } 33 34 public static implicit operator Nullable<T>(T value) 35 { 36 return new Nullable<T>(value); 37 } 38 39 public override string ToString() 40 { 41 if (!HasValue) 42 { 43 return String.Empty; 44 } 45 return this._value.ToString(); 46 } 47 48 }
泛型方法
泛型方法
1 public class Account 2 { 3 public string Name { get; private set; } 4 public decimal Balance { get; private set; } 5 6 public Account(string name, Decimal balance) 7 { 8 this.Name = name; 9 this.Balance = balance; 10 } 11 } 12 13 public static decimal AccunulateSimple(IEnumerable<Account> source) 14 { 15 decimal sum = 0; 16 foreach (Account a in source) 17 { 18 sum += a.Balance; 19 } 20 return sum; 21 }
调用用泛型方法
var accounts = new List<CreateFuncOfPattern.Account>() { new CreateFuncOfPattern.Account("A",1500), new CreateFuncOfPattern.Account("B",1000), new CreateFuncOfPattern.Account("C",1300), }; decimal amount = CreateFuncOfPattern.AccunulateSimple(accounts); Console.WriteLine(amount);
泛型方法可重载
本是菜鸟,偶做老鸟,略读半卷书,坐井说天阔。大志无所为,海斗量得失,年到老时方恨晚,怒指生不逢时。