精进不休 .NET 4.0 (4) - C# 4.0 新特性之命名参数和可选参数

[索引页]
[源码下载]


精进不休 .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
        {
void Page_Load() void Page_Load(object sender, EventArgs e)
                {
                        Write( "hello");
                        Write( "hello", "webabcd");
                        Write( "hello", p3: false, p2: "webabcd");
                }

void Write() 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
        {
string Hello() string Hello( string name)
                {
                        return "hello: " + name;
                }

                 public string Name { get; set; }

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

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

         public partial class DynamicBinding : System.Web.UI.Page
        {
void Page_Load() 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
        {
void Page_Load() 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 { get; set; }
                }

                 class Hero : Human
                {
                         public string Story { get; set; }
                }
        }
}

/*
运行结果:
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
        {
void Page_Load() 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
                {
void Write() void Write(T o)
                        {
                                HttpContext.Current.Response.Write(o.Name);
                        }
                }

                 class Human
                {
                         public string Name { get; set; }
                }

                 class Hero : Human
                {
                         public string Story { get; set; }
                }
        }
}

/*
运行结果:
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 = "";

static readonly object objLock = new object() static readonly object objLock = new object();

void Page_Load() 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);
                }

void ThreadWork() 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 = "";

static readonly object objLock = new object() static readonly object objLock = new object();

void Page_Load() 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);
                }

void ThreadWork() 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
[源码下载]

你可能感兴趣的:(C#,net,特性,休闲,精进)