C#:system.collections.generic(泛型)

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#算术运算符(/*-+)上。+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++完!

相关文章
相关标签/搜索