打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
.NET 委托类型解析(下)


来源:hystar

链接:http://www.cnblogs.com/lsxqw2004/archive/2008/12/17/1356705.html


委托协变(covariance)


允许创建一个委托,其返回的对象的类型是继承关系的,示例代码:


// 简单的集成关系的两个类

    class Car

    {

        public override string ToString()

        {

            return 'A stateless car';

        }

    }

    class SportsCar : Car

    {

        public override string ToString()

        {

            return 'A stateless sports car';

        }

    } 

    

    class Program

    {

        // 定义一个返回Car或SportsCar的委托

        public delegate Car ObtainVehicalDelegate();

 

        // 委托指向目标

        public static Car GetBasicCar()

        { return new Car(); }

 

        public static SportsCar GetSportsCar()

        { return new SportsCar(); }

        

 

        static void Main(string[] args)

        {

            ObtainVehicalDelegate targetA = new ObtainVehicalDelegate(GetBasicCar);

            Car c = targetA();

            Console.WriteLine(c);

 

            // 协变允许指定这样的目标方法

            ObtainVehicalDelegate targetB = new ObtainVehicalDelegate(GetSportsCar);

            SportsCar sc = (SportsCar)targetB();

            Console.WriteLine(sc);

            Console.ReadLine();

        }

    }


委托逆变,其中参数具有集成关系,委托签名的参数类型(派生类型)比方法具有的参数类型(基类型)更具体。定义一个参数类型是派生类型的委托,这个委托可以接收具有基类型参数的方法,因为派生类型隐式转换成了基类型。注意此方法必须接收与委托签名相同的参数类型(派生类型),虽然方法的签名中参数是基类型。


接下来说一下委托在多线程程序中的应用,主角有两个:ThreadStart和ParameterizedThreadStart,它们都定义与System.Threading命名空间下。


使用这两个委托,你可以以编程方式创建此线程来分担一些任务,步骤如下:


  1. 创建一个方法作为新线程的入口点。


  2. 创建一个ParameterizedThreadStart(或ThreadStart)委托,并把之前所定义的方法传给委托的构造函数。


  3. 创建一个Thread对象,并把ParameterizedThreadStart或ThreadStart委托作为构造函数的参数。


  4. 建立任意初始化线程的特性(名称、优先级等)。


  5. 调用Thread.Start()方法。


完成上述步骤,在第2步建立的委托所指向的方法将在线程中尽快开始执行。


ThreadStart委托指向一个没有参数、无返回值的方法,它在调用一个被设计用来仅仅在后台运行、而没有更多的交互时非常有用。它的局限在于无法给这个函数出入参数,所以在.Net2.0中出现了ParameterizedThreadStart了方法,它可以接受一个包含了任意个数的参数(传给它要调用的方法的)的Object类型对象做参数(即允许用户为新线程要执行的方法传入一个对象作为参数)。但注意这两种委托指向的函数的返回值都必须是void。


看看示例代码,首先是ThreadStart委托的:


public class Printer

    {

        public void PrintNumbers()

        {

            //具体实现省略

        }

    }

 

    class Program

    {

        static void Main(string[] args)

        {

            Printer p = new Printer();

            Thread bgroundThread = new Thread(new ThreadStart(p.PrintNumbers));

           

            // 控制此线程是否在后台运行?

            bgroundThread.IsBackground = true;

 

            bgroundThread.Start();

        }

}


接下来的代码示例了ParameterizedThreadStart委托的使用:


 //包装参数的类

    class AddParams

    {

        public int a;

        public int b;

        public AddParams(int numb1, int numb2)

        {

            a = numb1;

            b = numb2;

        }

    }

 

    class Program

    {

        static void Main(string[] args)

        {

            Console.WriteLine('主线程ID:{0}', Thread.CurrentThread.GetHashCode());

 

            //生成要传入的参数

            AddParams ap = new AddParams(10, 10);

 

            Thread t = new Thread(new ParameterizedThreadStart(Add));

            t.Start(ap);

        }

 

        //ParameterizedThreadStart委托调用的方法

        //使用AddParams类对象做参数

        public static void Add(object data)

        {

            if (data is AddParams)

            {

                Console.WriteLine('后台线程ID: {0}', Thread.CurrentThread.GetHashCode());

 

                AddParams ap = (AddParams)data;

                Console.WriteLine('{0} + {1} is {2}', ap.a, ap.b, ap.a + ap.b);

            }

        }

}


详细通过上面两段简单的代码示例,你已经对ThreadStart和ParameterizedThreadStart的使用有了全面的了解。


另外有一点需要说的,有些情况下可以省略这个委托对象的构造,即构造Thread对象时,直接向Thread的构造函数传入一个方法的名称,而不用先构造一个委托的对象。传入的方法既可以是静态方法也可以是实例方法。


另外委托在异步编程中的作用见异步编程的文章


参考资料:


C#与.Net3.0高级程序设计


C#与.Net2.0实战


CLR via C# 第二版


本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
.Net委托类型解析
转:要实现线程调用带参数的方法有两种办法。
C#,往线程里传参数的方法总结
C#中关于线程启动运行带多参数方法的操作
C#多线程委托ParameterizedThreadStart应用
C#中的多线程使用
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服