天天看點

精進不休 .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)

*    

        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

                        dynamic d = new dyanmicdemo();

                        response.write(d.hello("method"));

                        d.name = "hello: property";

                        response.write(d.name);

                        response.write(d["hello: indexer"]);

                        response.write(d.getnames().count.tostring());

                        // 注意:下面這句會報錯,因為不支援擴充方法

                        // response.write(d.getnames().last());

hello: method

hello: property

hello: indexer

3

3、泛型的協變的 demo

covariance.aspx.cs

泛型協變規則:

泛型參數受 out 關鍵字限制,隐式轉換目标的泛型參數類型必須是目前類型的“基類”

        public partial class covariance : system.web.ui.page

                        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 關鍵字限制,隐式轉換目标的泛型參數類型必須是目前類型的“子類”

        public partial class contravariance : system.web.ui.page

                        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);

webabcd

5、countdownevent 的 demo

countdowneventdemo.aspx.cs

* countdownevent - 線程、任務同步類。線程或任務一直阻塞到 countdownevent 的計數為 0 為止

* 1、當有新的需要同步的線程或任務産生時,就調用 addcount 增加 countdownevent 的計數

* 2、當有線程或任務到達同步點時,就調用 signal 函數減小 countdownevent 的計數

* 3、當 countdownevent 的計數為 0 時,就表示所有需要同步的任務已經完成。通過 wait 來阻塞線程

using system.threading;

        public partial class countdowneventdemo : system.web.ui.page

                private string _result = "";

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

                        // 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));

                                t2.start();

                                thread t3 = new thread(() => threadwork("ccc", timespan.fromseconds(3), countdown));

                                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 ,可以實作當指定的線程或任務數完成的時候取消阻塞

        public partial class barrierdemo : system.web.ui.page

                private barrier _barrier;

                        // 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);

void threadwork() void threadwork(string name, timespan sleeptime)

                        lock (objlock)

                                _result += "barrier之前:" + name + " " + datetime.now.tostring("hh:mm:ss");

                                _result += "<br />";

                        // 當指定數量的線程或任務完成後,同步這些線程或任務

                        _barrier.signalandwait();

                                _result += "barrier之後:" + name + " " + datetime.now.tostring("hh:mm:ss");

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