泛型和委托

泛型

什么是泛型

C# 语言和公共语言运行时 (CLR) 在 2.0 版本中添加了泛型。泛型将类型参数的概念引入 .NET Framework,这样就可以设计具有相同特征的类和方法:在客户端代码声明并初始化这些类和方法之前,这些类和方法会延迟指定一个或多个类型(使用占位符~3:数字代表类型参数个数)

泛型有什么用

使用泛型类型可以最大限度地重用代码、保护类型安全性以及提高性能。泛型最常见的用途是创建集合类 List< int>。

可以创建:泛型接口、泛型类、泛型方法、泛型事件和泛型委托

泛型的好处

  1. 增加类型的安全性
  2. 提高代码的重用

泛型的使用

问题:

自己编写一个入栈和出栈的通用类(任何数据类型都可以使用)类似与实现一个List的基本功能

    public class MyList<T>
    {
        //数组和集合
        T[] stack;
        int size;
        int stacPoint;//当前位置指针
        public MyList(int length)
        {
            this.size = length;
            stack = new T[size];
            stacPoint = -1;
        }

        /// <summary>
        /// 入栈
        /// </summary>
        /// <param name="item"></param>
        public void Add(T item)
        {
            if (stacPoint>=size)
            {
                Console.WriteLine("集合已满");
            }
            else
            {
                stacPoint++;
                stack[stacPoint] = item;
            }
        }
        /// <summary>
        /// 出栈
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public T Pop()
        {
            //提供的索引是存在元素的
            T data = stack[stacPoint];
            stacPoint--;
            return data;
        }
    }

泛型类的规范:

public class 类名<T> {类成员....}
  1. T:仅代表一个占位符,用T或者其他字母都行,只要符合C#命名规范都行,但是一般情况用T

  2. T:表示一个通用的数据类型,在使用的时候用实际类型代替

  3. T:泛型类可以在定义中可以包含多个任意类型参数,参数之间使用逗号隔开

    例如

    public class 类名<T1,T2,T3,....>{...}
    

    各种类型参数都可以用作成员变量的类型、属性、方法等成员的返回类型,以及方法的参数类型

总结:以上泛型类的使用,增加了类型安全,实例化时int类型的约束下是不能添加string类型。无需拆箱操作

泛型类型的问题

无法为泛型类型赋值初始化

因为泛型类型可以理解为泛指所有的数据类型,而所有的数据类型可分为:值类型和引用类型,而且不同的数据类型支持的默认值是不一样的。

注意:

  1. 不能随便假设泛型类型是某种类型,这种类型也许没有构造方法,也许是私有的
  2. 解决方案使用default关键字,如果defalut中指定的类型最终是引用类型则默认是null,如果是值类型那就给值类型对应的默认值,数值就是0.结构类型要根据具体的成员类型确定是0还是null

泛型的约束

给泛型类或者泛型方法中的泛型参数,这个参数需要给一个类型范围

泛型约束有哪些

  1. where T : struct 类型参数必须是值类型。
  2. where T : class 类型参数必须是引用类型。 此约束还应用于任何类、接口、委托或数组类型。
  3. where T : unmanaged 类型参数不能是引用类型,并且任何嵌套级别均不能包含任何引用类型成员。
  4. where T : new() 类型参数必须具有公共无参数构造函数。
  5. where T : <基类名> 类型参数必须是指定的基类或派生自指定的基类
  6. where T : <接口名称> 类型参数必须是指定的接口或实现指定的接口
  7. where T : U 为 T 提供的类型参数必须是为 U 提供的参数或派生自为 U 提供的参数。

dynamic动态类型:根据程序的执行去动态的获取当前类型是什么类型,类型永远不固定,最终类型取决于本次使用该数据时,其数据的类型

var推断类型:根据第一次的初始值推断出该类型,一旦类型被推断出,则该数据的类型就确定好了,之后不可更改

泛型方法

        //泛型方法
        static T Add<T>(T a,T b) where T:struct
        {
            dynamic a1 = a;
            dynamic b1 = b;
            return a1 + b1;
        }

dynamic和var和object 区别:

名 称 类 型 说 明 例子
dynamic 动态类型 根据程序的执行去动态的获取当前类型是什么类型,类型永远不固定,最终类型取决于本次使用该数据时,其数据的类型 dynamic a = 100; a = “123”;
var 推断类型 根据第一次的初始值推断出该类型,一旦类型被推断出,则该数据的类型就确定好了,之后不可更改 var i = 100;i=101;
object 对象类型 是所以类型的基类,故可以赋任何类型的值。 object o = 100; o = “123”;

委托技术的使用

委托是什么

  1. 委托是一种全新的面向对象语言特性,运行.NET平台上
  2. 基于委托,并发事件驱动程序变得非常简单
  3. 使用委托可以很大程度上简化多线程编程的难点

理解

  1. 委托可以看做一种数据类型,可以定义变量,但是他是一种特殊的变量
  2. 委托定义的变量能接收的数值只能使一个方法(函数),可以理解为委托就是方法的指针

委托的应用

主从窗体通信

在这里插入图片描述
在这里插入图片描述

发布了148 篇原创文章 · 获赞 365 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/chonbi/article/details/105054894