分享

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

 昵称10504424 2014-03-20


1. array是一个固定长度的,如果要动态的存储的话就不行了,虽然 System.Collections.ArrayList(),是一个动态的存储的容器,但是没有对存储中的数据进行一个约束,所以非泛型的容器和泛型 的容器相比存在两个问题:
                          1.性能问题;
                          2.安全问题;
=========================================================================================================
2.1.非泛型的命名空间:System.Collections    与   System.Collections.Specialized;
 
 
 


2.2.泛型命名空间:System.Collections.Generic;
 


=========================================================================================================
3.1.System.Collections.Generic.List<T>:表示可通过索引访问的对象的强类型列表。 提供用于对列表进行搜索、排序和操作的方法。
建立一个CZuigao类:
 

 

 

 


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

 

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():
 

 

 

 


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

 

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类进行输入输出:
 

 

 

 


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

 

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:
 


=========================================================================================================
3.3.System.Collections.Generic.Queue<T>类与上面的stack类方法相反为:表示对象的先进先出集合。
 

 

 

 


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

 

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:
 


=========================================================================================================
3.4.System.Collections.Generic.SortedSet<T>,表示按排序顺序保持的对象的集合。
首先要实现IComparer接口的Compare()方法:
 

 

 

 


1

2

3

4

5

6

7

8

9

10

11

 

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():
 

 

 

 


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

 

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()方法实现的;
现在还可以对其进行修改后看顶点:
 

 

 

 


1

2

3

4

 

//移除最高点操作:

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

完!
 

 

 

标签: C#:泛型

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多