黑马程序员--泛型的一些理解

本文聚焦于Windows Phone 7手机开发与.NET技术培训,深入探讨了泛型概念,包括装箱与拆箱、名称空间、泛型类与方法的应用。同时介绍了泛型集合如List<T>、Dictionary<K,V>,以及泛型类、委托的使用,并通过实例展示了如何在.NET框架中实现高效的类型安全编程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

---------------------- Windows Phone 7手机开发.Net培训、期待与您交流! ---------------------- ----------------------

泛型:在定义的时候不指定具体的类型结构,可以推迟到后面的声明或实例化时指定。


原因:避免在运行时强制转换或装箱拆箱操作的成本、风险。


名称空间:System.Collection.Generic


先了解下装箱和拆箱的概念:

装箱:把值类型转换为Object类型。

拆箱:取消装箱,从对象中提取值类型。

            int i = 123;
            object o = i;   //装箱:值类型到object类型

            int j = (int)o; //拆箱:object到值类型

装箱是隐式的,拆箱是显式的。装箱与拆箱过程需要大量的计算



对值类型装箱会在堆中分配一个对象实例。


堆(Heap):从高地址开始分配,程序员分配,比如C#中实例化 new

栈(Stack):从低地址开始分派,编译器自动分配,存放函数的参数值,局部变量等。



泛型适用范围:

泛型可以创建自己的泛型类、泛型方法、泛型委托、泛型借口、泛型事件等。最常见的用途是创建集合、类。


泛型的特点:

1.若实例化的参数类型相同,编译器会重复使用该类型,防止代码膨胀。

2.拥有丰富的元数据,可以应用于强大的反射技术。


泛型约束: where关键字

在定义泛型类时,可以在实例化类时对类型参数的类型种类施加限制。 如果客户端代码尝试使用某个约束所不允许的类型来实例化类,则会产生编译时错误。 这些限制称为约束。 约束是使用 where 上下文关键字指定的。 下表列出了六种类型的约束:

约束

说明

T:结构

类型参数必须是值类型。 可以指定除 Nullable 以外的任何值类型。

T:类

类型参数必须是引用类型;这一点也适用于任何类、接口、委托或数组类型。

T:new()

类型参数必须具有无参数的公共构造函数。 当与其他约束一起使用时,new() 约束必须最后指定。

T:<基类名>

类型参数必须是指定的基类或派生自指定的基类。

T:<接口名称>

类型参数必须是指定的接口或实现指定的接口。 可以指定多个接口约束。 约束接口也可以是泛型的。

T:U

为 T 提供的类型参数必须是为 U 提供的参数或派生自为 U 提供的参数。


例子: 

        public class BaseClass { } //声明父类
        public class PersonClass  : BaseClass { } //子类,继承父类BaseClass
        public class OtherClass<T> where T : BaseClass { }//泛型类。类型参数T只能继承于BaseClass

        OtherClass<PersonClass> other=new OtherClass<PersonClass>(); //这个声明能正常使用
表示T只能继承于BaseClasee,其实改成T where int  更好理解,

在里面定义的变量类型T只能来自 int类型。


泛型关键字:default及运算符 ==!=

在预先未知以下情况时,如何将默认值分配给参数化类型T:

1.T是引用类型还是值类型。

2.若T为值类型,则它是数值还是结构。

因此在不确定的情况下,避免使用运算符== 、 !=

示例:

        public class OtherClass<T> where T : BaseClass {
            T test=default (T);
            
            public void Msg()
            {
                if (test == null)
                {
                    MessageBox.Show("test的值为null");
                }
                else
                {
                    MessageBox.Show("test的值不为null");
                }
            }
        }
        



泛型集合:List<T> 、Dictionary<K,V>

List<T>  对应的是非泛型集合ArrayList。

它本身就是个类,所以在声明使用时,T要变成具体的数据结构。

            //非泛型,加入不同的值,会造成装箱拆箱的开销
            ArrayList alst = new ArrayList();
            alst.Add(123);
            alst.Add("字符串");
            //泛型List<T>
            List<int> lst = new List<int>();
            lst.Add(1);
            //lst.Add("2"); //报错,一方面限制了类型,一方面避免了装箱拆箱的开销
           

Dictionary<K,V>:表示键/值对集合。其中键的值K必须是唯一的。

Dictionary<K,V>.KeyColletion:表示Dictionary<K,V>的键集合。

Dictionary<K,V>.ValueColletion:表示Dictionary<K,V>的值集合。


泛型类:

过程:从一个现有的具体类开始,逐一将每个类型更改为类型参数,直至达到通用化和可用性的最佳平衡。

泛型类可以从具体的,封闭式构造或开放式构造基类继承:


        public class BaseClass { };
        public class BaseClassGeneric<T> { };
        public class PersonClass<T> : BaseClass { } //具体的
        public class PersonClosed<T> : BaseClassGeneric<int> { }; //封闭构造
        public class PersonOpen<T> : BaseClassGeneric<T> { };//开放构造



泛型方法:

在泛型类中定义

        class GenericList<T>
        {
            public void ShowMsg<Y>(T s)
            {
                T i = s;
                MessageBox.Show("你好"+s);   
            }

        }
        private void btnFxMethod_Click(object sender, EventArgs e)
        {
            GenericList<string> ls = new GenericList<string>();
            ls.ShowMsg("游客");
        }
    }


泛型委托:

可以定义自己的类型参数。引用泛型委托的代码可以指定类型参数以创建已关闭的构造类型,就像实例化泛型类或调用泛型方式一样。

示例:

        public delegate void Del<T>(T item); //定义个泛型委托
        public static void Notify(int i); //定义个方法
        Del<int> m1 = new Del<int>(Notify); //声明委托变量m1
        Del<int> m2 = Notify; //也可以这么声明


基础类库中的泛型:

System.Collections.Generic,其中包含了一些已经可以使用的泛型容器类和相关的接口。和早期版本的.NET框架提供的非泛型容器类相比,这些类和接口更高效且是类型安全的。在设计、实现自定义的容器类之前,请你考虑是否使用或继承所列出类中的一个。


泛型类或接口
描述
对应的非泛型类型
Collection<T>
ICollection<T>
为泛型容器提供基类
CollectionBase
ICollection
Comparer<T>
IComparer<T>
IComparable<T>
比较两个相同泛型类型的对象是否相等、可排序。
Comparer
IComparer
IComparable
Dictionary<K, V>
IDictionary<K,V>
表示用键组织的键/值对集合。
Hashtable
IDictionary
Dictionary<K, V>.KeyCollection
表示Dictionary<K, V>中键的集合。
None.
Dictionary<K, V>.ValueCollection
表示Dictionary<K, V>中值的集合。
None.
IEnumerable<T>
IEnumerator<T>
表示可以使用foreach 迭代的集合。
IEnumerable
IEnumerator
KeyedCollection<T, U>
表示有键值的集合。
KeyedCollection
LinkedList<T>
表示双向链表。
None.
LinkedListNode<T>
表示LinkedList<T>中的节点。
None.
List<T>
IList<T>
使用大小可按需动态增加的数组实现 IList 接口
ArrayList
IList
Queue<T>
表示对象的先进先出集合。
Queue
ReadOnlyCollection<T>
为泛型只读容器提供基类。
ReadOnlyCollectionBase
SortedDictionary<K, V>
 表示键/值对的集合,这些键和值按键排序并可按照键访问,实现IComparer<T>接口。
SortedList
Stack<T>
表示对象的简单的后进先出集合。
Stack


---------------------- Windows Phone 7手机开发.Net培训、期待与您交流! ---------------------- ----------------------


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值