[源码下载]
作者: webabcd
介绍
C# 4.0 的新特性
示例
1、 命名参数和可选参数的 Demo
NamedAndOptionalArguments.aspx.cs
代码
2、dynamic 的 Demo
DynamicBinding.aspx.cs
代码
3、泛型的协变的 Demo
Covariance.aspx.cs
代码
4、泛型的逆变的 Demo
Contravariance.aspx.cs
代码
5、CountdownEvent 的 Demo
CountdownEventDemo.aspx.cs
代码
6、Barrier 的 Demo
BarrierDemo.aspx.cs
代码
OK
[源码下载]
精进不休 .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
*/
* 命名参数和可选参数
* 命名参数:调用方法时,可以不按位置传递参数,而是指定参数的命名来传值
* 可选参数:声明方法中的参数时,可以为其设置默认值,那么在调用该方法时,这种可选参数是可以忽略的
*/
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 { get ; set ; }
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
*/
* 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 { get ; set ; }
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 { get ; set ; }
}
class Hero : Human
{
public string Story { get ; set ; }
}
}
}
/*
运行结果:
aaa
bbb
ccc
ddd
eee
fff
*/
泛型协变规则:
泛型参数受 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 { 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
{
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 { get ; set ; }
}
class Hero : Human
{
public string Story { get ; set ; }
}
}
}
/*
运行结果:
webabcd
*/
泛型逆变规则:
泛型参数受 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 { 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 = "" ;
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
*/
* 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
*/
* 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
[源码下载]