1. array是一個固定長度的,若是要動態的存儲的話就不行了,雖然 System.Collections.ArrayList(),是一個動態的存儲的容器,可是沒有對存儲中的數據進行一個約束,因此非泛型的容器和泛型 的容器相比存在兩個問題:
1.性能問題;
2.安全問題;
=========================================================================================================
2.1.非泛型的命名空間:System.Collections 與 System.Collections.Specialized;sql
2.2.泛型命名空間:System.Collections.Generic;c#
=========================================================================================================
3.1.System.Collections.Generic.List<T>:表示可經過索引訪問的對象的強類型列表。 提供用於對列表進行搜索、排序和操做的方法。
創建一個CZuigao類:安全
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication1 { class CZuigao { //2個私有字段用來存儲最高分學生的姓名和分數: private string name; private float score; //姓名和分數的屬性: public string Name { get { return name; } set { if( value.Length > 1 ) { name = value; } } } public float Score { get { return score; } set { if( float.Parse(value.ToString()) > 0.1f ) { score = (float)value; } } } //顯示存儲在私有字段中的信息(姓名 分數); public void printf() { Console.WriteLine("最高分爲:{1:f},最高分學生姓名是:{0}",name ,score ); } //構造函數: public CZuigao() { } public CZuigao(string n, float f) { Name = n; Score = f; } public CZuigao(string nn) : this(nn, 0.11f) { } public CZuigao(float ff) : this("沒有啊!", ff) { } } }
main():函數
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { //調用3個內部構造函數: CZuigao cz = new CZuigao("李異峯"); cz.printf(); CZuigao cz1 = new CZuigao(2.3f); cz1.printf(); CZuigao cz2 = new CZuigao("李曉峯", 3.6f); cz2.printf(); //直接初始化賦值屬性: CZuigao cz3 = new CZuigao() { Name = "我是屬性!",Score=8.8f }; cz3.printf(); Console.WriteLine("下面是list<t>:"); //list<T>: Program pro = new Program(); List<CZuigao> lzg = new List<CZuigao>() {new CZuigao("list1",1.1f),new CZuigao("list2",2.1f),new CZuigao("list3",3.3f) }; foreach( CZuigao scz in lzg ) { scz.printf(); } Console.WriteLine("\n添加CZuigao對象後:"); lzg.Add(cz ); foreach( CZuigao scz in lzg ) { scz.printf(); }; Console.ReadLine(); } } }
F5:性能
3.2.System.Collections.Generic.Stack<T>類是:表示相同任意類型的實例的可變大小的後進先出 (LIFO) 集合。
依然利用CZuigao類進行輸入輸出:ui
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { //調用3個內部構造函數: CZuigao cz = new CZuigao("李異峯"); cz.printf(); CZuigao cz1 = new CZuigao(2.3f); cz1.printf(); CZuigao cz2 = new CZuigao("李曉峯", 3.6f); cz2.printf(); //直接初始化賦值屬性: CZuigao cz3 = new CZuigao() { Name = "我是屬性!",Score=8.8f }; cz3.printf(); Console.WriteLine("\n下面是stack<t>:"); //stack<T>: Stack<CZuigao> szg = new Stack<CZuigao>(); szg.Push(new CZuigao("stack1", 9.8f)); szg.Push(new CZuigao("stack2",9.2f)); Console.WriteLine("最後輸入的姓名:{0},分數是:{1}",szg.Peek().Name,szg.Peek().Score.ToString() ); //添加CZuigao類的對象後: Console.WriteLine("\n下面是stack<t>添加CZuigao對象後的頂點:"); szg.Push(cz ); Console.WriteLine("頂點:姓名:{0},分數是:{1}", szg.Peek().Name, szg.Peek().Score.ToString()); //移除2條後: szg.Pop(); szg.Pop(); Console.WriteLine("\n下面是stack<t>移除CZuigao的2條後的頂點:"); Console.WriteLine("頂點:姓名:{0},分數是:{1}", szg.Peek().Name, szg.Peek().Score.ToString()); //在移除後: try { szg.Pop(); Console.WriteLine("頂點:姓名:{0},分數是:{1}", szg.Peek().Name, szg.Peek().Score.ToString()); } catch(Exception e) { Console.WriteLine("\n\nszg裏面爲null,詳情以下:{0}",e.ToString()); } Console.ReadLine(); } } }
F5:this
=========================================================================================================
3.3.System.Collections.Generic.Queue<T>類與上面的stack類方法相反爲:表示對象的先進先出集合。spa
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { //調用3個內部構造函數: CZuigao cz = new CZuigao("李異峯"); cz.printf(); CZuigao cz1 = new CZuigao(2.3f); cz1.printf(); CZuigao cz2 = new CZuigao("李曉峯", 3.6f); cz2.printf(); //直接初始化賦值屬性: CZuigao cz3 = new CZuigao() { Name = "我是屬性!",Score=8.8f }; cz3.printf(); Console.WriteLine("\n下面是Queue<T>:"); //Queue<T>: //初始化: Queue<CZuigao> qzg = new Queue<CZuigao>(); qzg.Enqueue(new CZuigao("queue1", 5.1f)); qzg.Enqueue(new CZuigao("queue2",5.2f)); //返回頂點: Console.WriteLine("頂點上的姓名是:{0},分數是:{1:f}",qzg.Peek().Name ,qzg.Peek().Score); //添加上面CZuigao類的對象: qzg.Enqueue(cz ); //返回頂點: Console.WriteLine("\n添加CZuIgao對象後:\n頂點上的姓名是:{0},分數是:{1:f}", qzg.Peek().Name, qzg.Peek().Score); //移除頂點: qzg.Dequeue(); //返回頂點: Console.WriteLine("\n移除最高點後:\n頂點上的姓名是:{0},分數是:{1:f}", qzg.Peek().Name, qzg.Peek().Score); Console.ReadLine(); } } }
F5:code
=========================================================================================================
3.4.System.Collections.Generic.SortedSet<T>,表示按排序順序保持的對象的集合。
首先要實現IComparer接口的Compare()方法:orm
public class IComparse:IComparer <CZuigao > { #region IComparer<CZuigao> 成員 int IComparer<CZuigao>.Compare(CZuigao x, CZuigao y) { if( x.Score > y.Score ) { return 1; } if( y.Score > x.Score ) { return -1; } else { return 0; } } #endregion }
再main():
static void Main(string[] args) { //初始化sortedset<T>: //***************注意啊 :在Generic.SortedSet類中要初始化構造函數**************************** System.Collections.Generic.SortedSet<CZuigao> sorzg = new SortedSet<CZuigao>(new IComparse()); //初始化5個CZuigao的對象: Queue<CZuigao> qzg = new Queue<CZuigao>(); for( int i = 0; i < 5; i++ ) { qzg.Enqueue(new CZuigao(string.Format("sortedset{0:d}", i), float.Parse(i.ToString()))); } //將Queue<CZuigao> qzg中的數據複製到sorzg裏面保存: foreach( CZuigao qq in qzg ) { sorzg.Add(qq); } //遍歷sortedset對象中的數據: Console.WriteLine("初始化後的遍歷:"); foreach( CZuigao sor in sorzg ) { Console.WriteLine("name={0},\tscore={1:f}", sor.Name, sor.Score); } //添加一條數據對象: sorzg.Add(new CZuigao("sortedset5",3.1f)); //遍歷sortedset對象中的數據: //下面是添加後的遍歷: Console.WriteLine("\n下面是添加後的遍歷:"); foreach( CZuigao sor in sorzg ) { Console.WriteLine("name={0},\tscore={1:f}", sor.Name, sor.Score); } Console.ReadLine(); }
F5後的數據比較:
這樣排序保存主要的是IComparer接口的Compare()方法實現的;
如今還能夠對其進行修改後看頂點:
//移除最高點操做: sorzg.Remove((CZuigao)sorzg.Max ); Console.WriteLine("\n當前sortedset內共有:{0:d}個對象數據;\n下面是移除最高點後的遍歷:",sorzg.Count); foreach( CZuigao sor in sorzg ) { Console.WriteLine("name={0},\tscore={1:f}", sor.Name, sor.Score); }
F5:
========================================================================================================
3.5. 在System.Collections.ObjectModel空間下有個 System.Collections.ObjectModel.ObservableCollection<T>類,表示一個動態數據集 合,在添加項、移除項或刷新整個列表時,此集合將提供通知。
其用法和list<t>相似:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 //using System.Collections; 7 //using System.Collections.Specialized; 8 using System.Collections.ObjectModel; 9 namespace ConsoleApplication1 10 { 11 class Program 12 { 13 static void Main(string[] args) 14 { 15 ObservableCollection<CZuigao> obzg = new ObservableCollection<CZuigao>() {new CZuigao ("observablecollection1",3.1f) }; 16 17 obzg.CollectionChanged+=obzg_CollectionChanged; 18 //添加對象: 19 obzg.Add(new CZuigao("observablecollection2", 8.1f)); 20 //遍歷當前全部的對象數據: 21 Console.WriteLine("\n當前全部的對象數據:"); 22 foreach( CZuigao ss in obzg ) 23 { 24 Console.WriteLine("name={0},\tscore={1:f}",ss.Name ,ss.Score ); 25 } 26 Console.WriteLine("\n"); 27 //移除: 28 obzg.RemoveAt(0); 29 Console.ReadLine(); 30 } 31 //public enum NotifyCollectionChangedAction 32 //{ 33 // Add = 0, 34 // Remove = 2, 35 //} 36 private static void obzg_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) 37 { 38 if( e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add ) 39 { 40 Console.WriteLine("用戶剛剛操做是添加操做,共添加了{0:d}個對象數據,詳情以下:",e.NewItems.Count ); 41 foreach( CZuigao ss in e.NewItems ) 42 { 43 Console.WriteLine("name={0},\tscore={1:f}",ss.Name,ss.Score ); 44 } 45 } 46 if( e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove ) 47 { 48 Console.WriteLine("是移除操做,共移除{0:d}個對象數據,詳情以下:",e.OldItems .Count ); 49 foreach( CZuigao ss in e.OldItems ) 50 { 51 Console.WriteLine("name={0},\tscore={1:f}", ss.Name, ss.Score); 52 } 53 } 54 } 55 56 57 } 58 59 }
F5:
=========================================================================================================
3.6.實際中還能夠自定義generic方法:
寫一個調換方法:
對值類型進行調換:
1 public static void Cdiaohuan<T>(ref T zg1,ref T zg2) 2 { 3 //下面這幾行代碼就是用來實現對象之間調換問題: 4 //首先就須要定義一個臨時的對象存儲變量: 5 T Temp; 6 Temp = zg1; 7 zg1 = zg2; 8 zg2 = Temp; 9 }
main():
1 static void Main(string[] args) 2 { 3 //用值類型來進行調換: 4 int a = 3, b = 5; 5 Cdiaohuan<Int32>(ref a ,ref b ); 6 //輸出a,b: 7 Console.WriteLine("a is {0:d}\tb is {1:d}",a ,b ); 8 Console.ReadLine(); 9 }
F5就不截屏了;
對引用類型:CZuigao的對象進行調換:
1 static void Main(string[] args) 2 { 3 // 對引用類型:CZuigao的對象進行調換: 4 CZuigao zg1 = new CZuigao() {Name="object1",Score=1.1f }; 5 CZuigao zg2 = new CZuigao() {Name="object2",Score=2.2f }; 6 //輸出對象中的數據: 7 Console.WriteLine("zg1對象中的:name={0}\tscore={1:f}",zg1.Name ,zg1.Score ); 8 Console.WriteLine("zg2對象中的:name={0}\tscore={1:f}",zg2.Name ,zg2.Score ); 9 //調用方法: 10 Cdiaohuan<CZuigao>(ref zg1, ref zg2); 11 Console.WriteLine("\n下面就是執行方法後的對象中的數據值:"); 12 //輸出對象中的數據: 13 Console.WriteLine("zg1對象中的:name={0}\tscore={1:f}", zg1.Name, zg1.Score); 14 Console.WriteLine("zg2對象中的:name={0}\tscore={1:f}", zg2.Name, zg2.Score); 15 Console.ReadLine(); 16 }
F5:
固然了輸出這兩句話能夠再寫個方法進行輸出,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
****還能夠將generic應用到class和interface/struct/委託裏,就是不能用在enum中:
寫一個generic的class:
1 namespace ConsoleApplication1 2 { 3 class CValue<T> 4 { 5 public T values1, values2; 6 public void printf() 7 { 8 Console.WriteLine("values1 is {0}\nvalues2 is {1}",values1.ToString(),values2.ToString()); 9 } 10 } 11 }
在main()中實現:
1 static void Main(string[] args) 2 { 3 CValue<Int32> cv = new CValue<int>(); 4 cv.values1 = 1; 5 cv.values2 = 3; 6 cv.printf(); 7 8 Console.ReadLine(); 9 }
=========================================================================================================
3.7.上面的這實例仍是存在必定的漏洞,好比說上面3.6.中說的一個方法:public static void Cdiaohuan<T>(ref T zg1,ref T zg2),能夠對值類型和引用類型就行調換,若是咱們強制要求只能調換object類型呢?這樣的話就要用到generic中的約束,where和sqlser中的where的意思有點相似篩選符合的要求:
看看3.6.中的 public static void Cdiaohuan<T>(ref T zg1,ref T zg2):
1 public static void Cdiaohuan<T>(ref T zg1,ref T zg2) 2 { 3 //下面這幾行代碼就是用來實現對象之間調換問題: 4 //首先就須要定義一個臨時的對象存儲變量: 5 T Temp; 6 Temp = zg1; 7 zg1 = zg2; 8 zg2 = Temp; 9 }
添加個object約束:
1 public static void Cdiaohuan<T>(ref T zg1,ref T zg2) where T :Class 2 { 3 //下面這幾行代碼就是用來實現對象之間調換問題: 4 //首先就須要定義一個臨時的對象存儲變量: 5 T Temp; 6 Temp = zg1; 7 zg1 = zg2; 8 zg2 = Temp; 9 }
若是仍是讓方法執行value的調換的話:
1 static void Main(string[] args) 2 { 3 int a = 3, b = 6; 4 try { Cdiaohuan<Int32>(ref a, ref b); } 5 catch( Exception ex ) { Console.WriteLine(ex.ToString()); } 6 7 Console.ReadLine(); 8 }
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
執行object類型的調換:
在此以前在 class CZuigao 完成接口的實現; class CZuigao:IComparable <CZuigao > :
1 #region IComparable<CZuigao> 成員 2 int IComparable<CZuigao>.CompareTo(CZuigao other) 3 { 4 if( other.Score > this.Score ) { return -1; } 5 else if( other.Score == this.Score ) { return 0; } 6 else { return 1; } 7 } 8 #endregion
1 static void Main(string[] args) 2 { 3 //初始化List<T>,並添加2條對象數據: 4 List<CZuigao> lzg = new List<CZuigao>() { new CZuigao("yueshu1", 1.1f), new CZuigao("yueshu2", 2.2f) }; 5 Console.WriteLine("List<T>中的對象數據條:"); 6 //遍歷輸出: 7 foreach( CZuigao ss in lzg ) { Console.WriteLine("name={0}\tscore={1:f}", ss.Name, ss.Score); } 8 CZuigao zg1 = (CZuigao)lzg.Min(); 9 CZuigao zg2 = (CZuigao)lzg.Max(); 10 //print當前CZuigao的zg1和zg2對象中的數據: 11 Console.WriteLine("\nzg1:\nname={0}\tscore={1:f}",zg1.Name ,zg1.Score ); 12 Console.WriteLine("zg2:\nname={0}\tscore={1:f}\n", zg2.Name, zg2.Score); 13 Cdiaohuan<CZuigao>(ref zg1 ,ref zg2 ); 14 //print執行Cdiaohuan()方法後的CZuigao的zg1和zg2對象中的數據: 15 Console.WriteLine("\nzg1:\nname={0}\tscore={1:f}", zg1.Name, zg1.Score); 16 Console.WriteLine("zg2:\nname={0}\tscore={1:f}\n", zg2.Name, zg2.Score); 17 Console.ReadLine(); 18 }
F5:
ok!
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
最後總結下where中有哪些約束類型:
1.where t:class 類型參數爲object
2.where t:struct 類型參數爲vale type
3.where t:new() 必須包含一個構造函數
4.where t:baseClass 必須是它的派生類
5.where t:interface 必須實現該接口;
不能將類型參數運用在c#算術運算符(/*-+)上。+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++完!