• 集合和泛型


    泛型 和 集合

    更专业的解析强点击上面蓝色文字。

    集合类底层接口关系图

    所有的集合都是继承自IEnumerable。集合总体可以分为以下几类:

    • 关联/非关联型集合,
    • 顺序/随机访问集合,
    • 顺序/无序集合,
    • 泛型/非泛型集合,
    • 线程集合。
      各集合类底层接口关系图:
      在这里插入图片描述
      在这里插入图片描述

    泛型

    为什么要有泛型

    我们常常需要创建能用于任何数据类型的类或方法,多态和继承并不总能"药到病除"。在.Net2.0之前,如果方法需要适配任意类型,就只能使用System.Object。这会带来两个问题。
    1.类型安全
    2.装箱

    泛型约束

    泛型约束告诉编译器,在使用某个泛型时,只有某些类型能够作为泛型实参。

    每个泛型参数可以有至多一个主要约束,泛型的主要约束是指指定泛型参数必须是或者继承自某个引用类型,有两个特殊的主要约束:class和struct,分别代表泛型参数引用类型和值类型。

    每个泛型参数可以有无数个次要约束,次要约束和主要约束的语法基本相同,但它规定的是某个泛型参数必须实现所有次要约束指定的接口。

    public class ClassT1<T> where T : Exception
        {
            private T myException;
            public ClassT1(T t)
            {
                myException = t;
            }
            public override string ToString()
            {
                //主要约束保证了myException拥有source成员
                return myException.Source;
            }
        }
        public class ClassT2<T> where T : class
        {
            private T myT;
            public void Clear()
            {
                //T是引用类型,可以置null
                myT = null;
            }
        }
        public class ClassT3<T> where T : struct
        {
            private T myT;
            public override string ToString()
            {
                //T是值类型,不会发生NullReferenceException异常
                return myT.ToString();
            }
        }
    
    • 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

    泛型主要约束示例:

    public T Create<T>(T element) where T : EntityBase
    {
    }
    public T Create<T>(T element) where T : EntityBase
    {
    }
    public T Create<T>(T element) where T : IFormattable
    {
    }
    public T Create<T>(T element) where T : new()
    {
    }
    public T Create<T>(T element) where T : class
    {
    }
    public T Create<T>(T element) where T : struct
    {
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    1 int[]是引用类型还是值类型

    数组类型是一族类型,它们都继承自System.Array,而System.Array又继承自System.Object。所有数组的类型都是引用类型。

    引用类型的数组和值类型的数组的内存分配:
    在这里插入图片描述

    集合

    在这里插入图片描述
    祖宗: IEnumerable

    此接口只有一个方法 GetEnumerator();

    是FrameWork为了实现迭代器模式设计的接口。
    所有继承了IEnumerable的类,要使用foreach迭代器时,就需要使用该方法。因此也只有实现了该接口的类才可以使用foreach。

    ICollection继承自IEnumerable,IList继承自ICollection

    这两个接口都是为了给集合提供一些公用的方法。只是分了两个层次,IList比ICollection多几个方法,增加,移除成员。
    可以简单理解为:ICollection主要针对静态集合;IList主要针对动态集合。

    IListIList,ICollection,IEnumerable在命名空间System.Collections中。

    IList,ICollection,IEnumerable。在System.Collections.Generic 命名空间中。

    IList,ICollection,IEnumerable。是2.0引入泛型以后新增的。主要是提高重用性与类型安全。

    IEnumerable继承自IEnumerable

    ICollection继承自IEnumerable

    IList继承自ICollection

    因此可以完全使用泛型接口,而放弃使用ICollection和IList。泛型接口提供了更好的类型安全和编译时的检验。

    补充:

    IEnumerable和IEnumerable都只有一个方法。

    ICollection和ICollection的结构是不一样的。ICollection比ICollection多几个方法。它包含了几个IList中的几个方法。也许是对以前的改进。
    ————————————————

    ICollection主要针对静态集合;IList主要针对动态集合
    IEnumerable继承自IEnumerable
    ICollection继承自IEnumerable
    IList继承自ICollection

    IEnumerable接口

    实现了IEnumerable接口的集合表明该集合能够提供一个enumerator(枚举器)对象,支持当前的遍历集合。
    IEnumerable接口只有一个成员GetEnumerator()方法。
    
    • 1
    • 2

    IEnumerator接口

    IEnumerator接口是只读的,包括以下三个成员:

    • MoveNext()方法调整遍历指针移向集合的下一个元素。

    注意,遍历指针的初始位置是集合中第一个元素的前面。要指向第一个元素,必须先调用一次MoveNext()方法。该方法返回一个布尔值,如果成功遍历到下一个元素,则返回true;如果指针移出末尾,则返回false。

    • Reset()方法用于设置遍历指针指向初始位置,即集合中第一个元素的前面。
    • Current属性返回集合中当前对象的引用。

    IEnumerable和IEnumerator的区别

    1、一个Collection要支持foreach方式的遍历,必须实现IEnumerable接口(亦即,必须以某种方式返回IEnumerator object)。 
    2、IEnumerator object具体实现了iterator(通过MoveNext(),Reset(),Current)。 
    3、从这两个接口的用词选择上,也可以看出其不同:IEnumerable是一个声明式的接口,声明实现该接口的class是“可枚举
    (enumerable)”的,但并没有说明如何实现枚举器(iterator);
    IEnumerator是一个实现式的接口,IEnumerator object就是一个iterator。 
    4、IEnumerable和IEnumerator通过IEnumerable的GetEnumerator()方法建立了连接,
    client可以通过IEnumerable的GetEnumerator()得到IEnumerator object,在这个意义上,
    将GetEnumerator()看作IEnumerator object的factory method也未尝不可。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    ICollection集合

    该接口是IEnumerable接口的子接口,定义了集合的大小、IEnumerator接口和同步方法。在IEnumerable接口的基础上增加了以下功能。
    Count;该属性返回集合中元素的数目。
    CopyTo(Array array, int index);该方法用于实现从集合中拷贝元素到一个一维数组中。

    IList接口

    Add()和Insert()方法用于向集合中添加条目,使用索引来指定项目要插入的位置,其中首元素的索引为0;Add()将新条目添加到尾部。
    Remove()和RemoveAt()用于从列表中删除条目。Clear()用于删除所有条目。
    IndexOf和Contains()用于搜索该列表。
    Item属性用于获取或设置索引指定的值。C#中可以使用[]运算符进行访问。

    IList接口和ArrayList类的目的是实现动态数组,ArrayList是IList的一个实现。

    IDictionary接口

    IDictionary接口是一个包含一组”关键字/值”对的数据结构,每个值都由相应的关键字来定义。关键字和值可以是任何数据类型,关键字必须唯一且非空。
    Add()方法添加一个指定的关键字和值的条目到IDictionary接口。
    Item属性检索指定关键字所对应的值。
    Keys和Values属性分别返回包含所有关键字和值的集合。
    Remove()用于删除指定关键字对应的条目。Clear()用于删除所有条目。
    GetEnumator()返回一个IDictionaryEnumerator,可用于遍历IDictionary接口。

    ObservableCollectin

    是从Collection继承而来的。

    什么时候要用List:
    要对集合数据进行处理,从中筛选数据或者排序。

    ————————————————
    版权声明:本文为CSDN博主「kalvin_y_liu」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/kalvin_y_liu/article/details/117825389

    ObservableCollection和List的区别

    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace FunWithObservableCollection
    {
        class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("***** Fun with Observable Collections *****\n");
    
                // Make a collection to observe and add a few Person objects. 
                ObservableCollection<Person> people = new ObservableCollection<Person>()
                {
                    new Person{ FirstName = "Peter", LastName = "Murphy", Age = 52 },
                    new Person{ FirstName = "Kevin", LastName = "Key", Age = 48 },
                };
                
                // Wire up the CollectionChanged event. 
                people.CollectionChanged += people_CollectionChanged;
    
                // Now add a new item.
                people.Add(new Person("Fred", "Smith", 32));
    
                // Remove an item.
                people.RemoveAt(0);
    
                Console.ReadLine();
            }
    
            #region CollectionChanged event handler
            static void people_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
            {
                // What was the action that caused the event?
                Console.WriteLine("Action for this event: {0}", e.Action);
    
                // They removed something. 
                if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
                {
                    Console.WriteLine("Here are the OLD items:");
                    foreach (Person p in e.OldItems)
                    {
                        Console.WriteLine(p.ToString());
                    }
                    Console.WriteLine();
                }
    
                // They added something. 
                if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
                {
                    // Now show the NEW items that were inserted.
                    Console.WriteLine("Here are the NEW items:");
                    foreach (Person p in e.NewItems)
                    {
                        Console.WriteLine(p.ToString());
                    }
                }
            } 
            #endregion
        }
    }
    
    
    • 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
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
  • 相关阅读:
    基于JAVA医院管理系统计算机毕业设计源码+系统+mysql数据库+lw文档+部署
    JAVA毕业设计考勤管理系统计算机源码+lw文档+系统+调试部署+数据库
    攻防世界WEB练习-easyupload
    产品经理相关的学习网站
    Allegro如何设置丝印位号优先显示操作指导
    Oracle 高可用 阅读笔记
    Jenkins容器内安装python3
    【蒸汽冷凝器型号和PI控制】具有PID控制的蒸汽冷凝器的动力学模型(Matlab&Simulink)
    QT基础入门——界面布局和常用控件(四)
    Android OkHttp/Retrofit框架使用Interceptor 抓包/mock数据
  • 原文地址:https://blog.csdn.net/kalvin_y_liu/article/details/127453526