A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 刘亚龙 中级黑马   /  2012-12-6 08:53  /  1231 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

协变:协变允许所调用方法的返回类型可以是委托的返回类型的派生类型,当委托方法的返回类型具有的派生类型比委托签名更大时,就成为协变委托方法。因为方法的返回类型比委托签名的返回类型更具体,所以可对其进行隐式转换。
逆变:逆变允许将带有派生参数的方法用作委托,当委托签名具有一个或多个参数,并且这些参数的类型派生自方法参数的类型时,就成为逆变委托方法。因为委托方法签名参数比方法参数更具体,所以可以在传递给处理程序方法时对它们进行隐式转换。
代码示例:

声明委托和需要使用的类
public delegate Person PointPerson(int i);//声明委托,返回第i个人
    public delegate int Position(Student s);//声明委托,返回指定学生的位置
    public class Person
    {
        public string name;
        public char sex;
        public Person(string n, char s)
        {
            name = n;
            sex = s;
        }
    }
    public class Student:Person //派生类
    {
        public string school;
        public Student(string n, char s, string sch)
            : base(n, s)
        {
            school = sch;
        }
    }
创建人的集合类和学生的集合类
public class Persons //若干个人的集合
    {
        public Person[] p = new Person[3];//创建3个人的集合
        public Person getPetson(int i)    //得到指定位置的人,Persons中的方法
        {
            if (i < 0 || i > p.Length)
                return p[0];
            else
                return p;
        }
        public int getPos(Person per)   //返回指定人的位置,Persons中的方法
        {
            int k = -1;
            for (int i = 0; i < p.Length; i++)
            {
                if (p.name == per.name && p.sex == per.sex)
                {
                    k = i;
                    break;
                }
            }
            return k;
        }
    }
    public class Students    //若干个学生的集合
    {
        public Student[] s = new Student[3];
        public Student getStudent(int i) //得到指定位置的学生,Students中的方法
        {
            if (i < 0 || i > s.Length)
                return s[0];
            else
                return s;
        
        }
        public int getPos(Student stu) //得到指定学生的位置,Students中的方法
        {
            int k = -1;
            for (int i = 0; i < s.Length; i++)
            {
                if (s.name == stu.name && s.sex == stu.sex)
                {
                    k = i;
                    break;
                }
            }
            return k;
        }
    }
主函数中使用
class Program
    {
        static void Main(string[] args)
        {
            //创建学生集合并存入3个学生的数据
            Students stus = new Students();
            stus.s[0] = new Student("tom", '男', "电子科技大学");
            stus.s[1] = new Student("david", '男', "清华大学");
            stus.s[2] = new Student("lily", '女', "北京大学");
            //创建返回值为Person类型的委托对象并指定引用Students集合的getStudent方法
            PointPerson point = new PointPerson(stus.getStudent);
            for (int i = 0; i < 3; i++)
            {
                Person p = point(i);                       //协变方法调用
                Console.WriteLine("姓名:{0} 性别:{1}", p.name, p.sex);
            }
            //创建人集合并存入3个人的数据
            Persons pers = new Persons();
            pers.p[0] = new Person("tom", '男');
            pers.p[1] = new Person("david", '男');
            pers.p[2] = new Person("lily", '女');
            //创建参数为Students的委托对象,并指定引用Persons集合的getPos方法
            Position position = new Position(pers.getPos);
            int k = position(stus.s[2]);                   //逆变委托方法调用
            Console.WriteLine("这个学生在persons中是第{0}个人", k + 1);

            Console.ReadKey();
        }
    }

评分

参与人数 1技术分 +2 收起 理由
宋天琪 + 2

查看全部评分

2 个回复

倒序浏览
值得学习ing!
回复 使用道具 举报
受教 果然是高手
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马