zoukankan      html  css  js  c++  java
  • 精进不休 .NET 4.0 (4) C# 4.0 新特性之命名参数和可选参数, 动态绑定(dynamic), 泛型协变和逆变, CountdownEvent, Barrier

    [索引页]
    [源码下载]


    精进不休 .NET 4.0 (4) - C# 4.0 新特性之命名参数和可选参数, 动态绑定(dynamic), 泛型协变和逆变, CountdownEvent, Barrier


    作者:webabcd


    介绍
    C# 4.0 的新特性
    • Named And Optional Arguments - 命名参数和可选参数 
    • Dynamic Binding - 动态绑定(dynamic 用于动态编程,其依赖于Dynamic Language Runtime) 
    • Covariance - 泛型的协变 
    • Contravariance - 泛型的逆变 
    • CountdownEvent - 线程、任务同步类。线程或任务一直阻塞到 CountdownEvent 的计数为 0 为止
    • Barrier - 线程、任务同步类。其用来同步一个线程组或任务组中所有的线程或任务,先到达的线程或任务在此阻塞


    示例
    1、 命名参数和可选参数的 Demo
    NamedAndOptionalArguments.aspx.cs
    代码
    /*
     * 命名参数和可选参数
     * 命名参数:调用方法时,可以不按位置传递参数,而是指定参数的命名来传值
     * 可选参数:声明方法中的参数时,可以为其设置默认值,那么在调用该方法时,这种可选参数是可以忽略的
     
    */

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;

    namespace CSharp
    {
        
    public partial class NamedAndOptionalArguments : System.Web.UI.Page
        {
            
    protected void Page_Load(object sender, EventArgs e)
            {
                Write(
    "hello");
                Write(
    "hello""webabcd");
                Write(
    "hello", p3: false, p2: "webabcd");
            }

            
    private void Write(string p1, string p2 = "p2"bool p3 = true)
            {
                Response.Write(
    string.Format("p1:{0}; p2:{1}; p3:{2}", p1, p2, p3.ToString()));
                Response.Write(
    "<br />");
            }
        }
    }

    /*
    运行结果:
    p1:hello; p2:p2; p3:True
    p1:hello; p2:webabcd; p3:True
    p1:hello; p2:webabcd; p3:False
    */


    2、dynamic 的 Demo
    DynamicBinding.aspx.cs
    代码
    /*
     * dynamic - 用于动态编程,其依赖于Dynamic Language Runtime(DLR)
     * 
     
    */

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;

    namespace CSharp
    {
        
    public class DyanmicDemo
        {
            
    public string Hello(string name)
            {
                
    return "hello: " + name;
            }

            
    public string Name { getset; }

            
    public string this[string value]
            {
                
    get
                {
                    
    return value;
                }
            }

            
    public dynamic GetNames()
            {
                List
    <string> names = new List<string>() { "web""webabc""webabcd" };
                
                
    return names;
            }
        }

        
    public partial class DynamicBinding : System.Web.UI.Page
        {
            
    protected void Page_Load(object sender, EventArgs e)
            {
                dynamic d 
    = new DyanmicDemo();

                Response.Write(d.Hello(
    "method"));
                Response.Write(
    "<br />");

                d.Name 
    = "hello: property";
                Response.Write(d.Name);
                Response.Write(
    "<br />");

                Response.Write(d[
    "hello: indexer"]);
                Response.Write(
    "<br />");

                Response.Write(d.GetNames().Count.ToString());

                
    // 注意:下面这句会报错,因为不支持扩展方法
                
    // Response.Write(d.GetNames().Last());
            }
        }
    }

    /*
    运行结果:
    hello: method
    hello: property
    hello: indexer
    3
    */


    3、泛型的协变的 Demo
    Covariance.aspx.cs
    代码
    /*
    泛型协变规则:
    泛型参数受 out 关键字约束,隐式转换目标的泛型参数类型必须是当前类型的“基类”
    */

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;

    namespace CSharp
    {
        
    public partial class Covariance : System.Web.UI.Page
        {
            
    protected void Page_Load(object sender, EventArgs e)
            {
                List
    <Human> human = new List<Human>();
                human.Add(
    new Human { Name = "aaa" });
                human.Add(
    new Human { Name = "bbb" });
                human.Add(
    new Human { Name = "ccc" });

                List
    <Hero> hero = new List<Hero>();
                hero.Add(
    new Hero { Name = "ddd", Story = "尿床" });
                hero.Add(
    new Hero { Name = "eee", Story = "撒谎" });
                hero.Add(
    new Hero { Name = "fff", Story = "打架" });

                
    /* 
                 * List<T> 实现了如下接口 IEnumerable<out T> ,所以可以实现协变
                 * public interface IEnumerable<out T> : IEnumerable
                 * {
                 *     // Summary:
                 *     //     Returns an enumerator that iterates through the collection.
                 *     //
                 *     // Returns:
                 *     //     A System.Collections.Generic.IEnumerator<T> that can be used to iterate through
                 *     //     the collection.
                 *     IEnumerator<T> GetEnumerator();
                 * }
                 
    */

                
    // Hero 的基类是 Human,所以 Hero 可以协变到 Human,所以下面的表达式成立
                List<Human> list = human.Union(hero).ToList();
                
    foreach (Human h in list)
                {
                    Response.Write(h.Name);
                    Response.Write(
    "<br />");
                }
            }

            
    class Human
            {
                
    public string Name { getset; }
            }

            
    class Hero : Human
            {
                
    public string Story { getset; }
            }
        }
    }

    /*
    运行结果:
    aaa
    bbb
    ccc
    ddd
    eee
    fff
    */


    4、泛型的逆变的 Demo
    Contravariance.aspx.cs
    代码
    /*
    泛型逆变规则:
    泛型参数受 in 关键字约束,隐式转换目标的泛型参数类型必须是当前类型的“子类”
    */

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;

    namespace CSharp
    {
        
    public partial class Contravariance : System.Web.UI.Page
        {
            
    protected void Page_Load(object sender, EventArgs e)
            {
                IOutput
    <Human> human = new Output<Human>();

                
    // 因为 IOutput<in T> ,并且 Human 的子类是 Hero ,所以 IOutput<Human> 可以逆变到 IOutput<Hero>
                IOutput<Hero> hero = human;
                hero.Write(
    new Hero { Name = "webabcd" });
            }

            
    interface IOutput<in T>
            {
                
    void Write(T o);
            }

            
    class Output<T> : IOutput<T>
                
    where T : Human
            {
                
    public void Write(T o)
                {
                    HttpContext.Current.Response.Write(o.Name);
                }
            }

            
    class Human
            {
                
    public string Name { getset; }
            }

            
    class Hero : Human
            {
                
    public string Story { getset; }
            }
        }
    }

    /*
    运行结果:
    webabcd
    */


    5、CountdownEvent 的 Demo
    CountdownEventDemo.aspx.cs
    代码
    /*
     * CountdownEvent - 线程、任务同步类。线程或任务一直阻塞到 CountdownEvent 的计数为 0 为止
     * 1、当有新的需要同步的线程或任务产生时,就调用 AddCount 增加 CountdownEvent 的计数
     * 2、当有线程或任务到达同步点时,就调用 Signal 函数减小 CountdownEvent 的计数
     * 3、当 CountdownEvent 的计数为 0 时,就表示所有需要同步的任务已经完成。通过 Wait 来阻塞线程
     
    */

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;

    using System.Threading;

    namespace CSharp
    {
        
    public partial class CountdownEventDemo : System.Web.UI.Page
        {
            
    private string _result = "";

            
    private static readonly object objLock = new object();

            
    protected void Page_Load(object sender, EventArgs e)
            {
                
    // CountdownEvent(int initialCount) - 实例化一个 CountdownEvent
                
    //     int initialCount - 初始计数
                using (var countdown = new CountdownEvent(1))
                {
                    Thread t1 
    = new Thread(() => ThreadWork("aaa", TimeSpan.FromSeconds(1), countdown));
                    
    // 增加 1 个计数
                    countdown.AddCount();
                    t1.Start();

                    Thread t2 
    = new Thread(() => ThreadWork("bbb", TimeSpan.FromSeconds(2), countdown));
                    countdown.AddCount();
                    t2.Start();

                    Thread t3 
    = new Thread(() => ThreadWork("ccc", TimeSpan.FromSeconds(3), countdown));
                    countdown.AddCount();
                    t3.Start();

                    
    // 减少 1 个计数
                    countdown.Signal();
                    
    // 阻塞当前线程,直到 CountdownEvent 的计数为零
                    countdown.Wait();
                }

                Response.Write(_result);
            }

            
    private void ThreadWork(string name, TimeSpan sleepTime, CountdownEvent countdown)
            {
                Thread.Sleep(sleepTime);

                _result 
    += "hello: " + name + " " + DateTime.Now.ToString("HH:mm:ss");
                _result 
    += "<br />";

                
    // 减少 1 个计数
                countdown.Signal();
            }
        }
    }

    /*
    运行结果:
    hello: aaa 15:18:55
    hello: bbb 15:18:56
    hello: ccc 15:18:57
    */


    6、Barrier 的 Demo
    BarrierDemo.aspx.cs
    代码
    /*
     * Barrier - 线程、任务同步类。其用来同步一个线程组或任务组中所有的线程或任务,先到达的线程或任务在此阻塞
     * 1、实例化 Barrier 指定其需要阻塞的线程或任务数
     * 2、通过 SignalAndWait ,可以实现当指定的线程或任务数完成的时候取消阻塞
     
    */

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;

    using System.Threading;

    namespace CSharp
    {
        
    public partial class BarrierDemo : System.Web.UI.Page
        {
            
    private Barrier _barrier;
            
    private string _result = "";

            
    private static readonly object objLock = new object();

            
    protected void Page_Load(object sender, EventArgs e)
            {
                
    // Barrier(int participantCount) - 实例化一个 Barrier
                
    //     int participantCount - 需要阻塞的相关线程或任务数
                _barrier = new Barrier(2);

                Thread t1 
    = new Thread(() => ThreadWork("aaa", TimeSpan.FromSeconds(1)));
                t1.Start();
                Thread t2 
    = new Thread(() => ThreadWork("bbb", TimeSpan.FromSeconds(2)));
                t2.Start();
                Thread t3 
    = new Thread(() => ThreadWork("ccc", TimeSpan.FromSeconds(3)));
                t3.Start();

                Thread.Sleep(
    5 * 1000);
                Response.Write(_result);
            }

            
    private void ThreadWork(string name, TimeSpan sleepTime)
            {
                
    lock (objLock)
                {
                    _result 
    += "Barrier之前:" + name + " " + DateTime.Now.ToString("HH:mm:ss");
                    _result 
    += "<br />";
                }

                Thread.Sleep(sleepTime);

                
    // 当指定数量的线程或任务完成后,同步这些线程或任务
                _barrier.SignalAndWait();

                
    lock (objLock)
                {
                    _result 
    += "Barrier之后:" + name + " " + DateTime.Now.ToString("HH:mm:ss");
                    _result 
    += "<br />";
                }
            }
        }
    }

    /*
    运行结果:
    Barrier之前:aaa 17:38:01
    Barrier之前:ccc 17:38:01
    Barrier之前:bbb 17:38:01
    Barrier之后:bbb 17:38:03
    Barrier之后:aaa 17:38:03
    */


    OK
    [源码下载]
  • 相关阅读:
    常用linux命令及其设置
    shell脚本编写步骤及其常用命令和符号
    浏览器访问php脚本通过sendmail用mail函数发送邮件
    windows server 定期备份数据库脚本
    图片垂直水平居中
    "!function",自执行函数表达式
    jQuery(function(){})与(function(){})(jQuery) 的区别
    在Windows Server 2019通过Docker Compose部署Asp.Net Core
    Redis集群同步问题
    webapi跨域使用session
  • 原文地址:https://www.cnblogs.com/webabcd/p/1744899.html
Copyright © 2011-2022 走看看