編寫高質量代碼改善C#程序的157個建議[爲泛型指定初始值、使用委託聲明、使用Lambda替代方法和匿名方法]

前言html

  泛型並非C#語言一開始就帶有的特性,而是在FCL2.0以後實現的新功能。基於泛型,咱們得以將類型參數化,以便更大範圍地進行代碼複用。同時,它減小了泛型類及泛型方法中的轉型,確保了類型安全。委託自己是一種引用類型,它保存的也是託管堆中對象的引用,只不過這個引用比較特殊,它是對方法的引用。事件自己也是委託,它是委託組,C#中提供了關鍵字event來對事件進行特別區分。一旦咱們開始編寫稍微複雜的C#代碼,就確定離不開泛型、委託和事件。本章將針對這三個方面進行說明。算法

本文已更新至http://www.cnblogs.com/aehyok/p/3624579.html 。本文主要學習記錄如下內容:安全

  建議3五、使用default爲泛型類型指定初始值異步

  建議3六、使用FCL中的委託聲明學習

  建議3七、使用lambda表達式代替方法和匿名方法this

建議3五、使用default爲泛型類型指定初始值編碼

  有些算法,好比泛型集合List<T>的Find算法,所查找的對象有可能會是值類型,也有多是引用類型。在這種算法內部,咱們經常會爲這些值類型變量或引用類型變量指定默認值。因而,問題來了:值類型變來那個的默認初始值是0值,而引用類型變量的默認初始值是null值,顯然,這會致使下面編譯出錯:spa

C#編譯器會阻止這樣的代碼經過編譯。要讓編譯器接收爲一個泛型類型參數指定一個初始值,最穩當的辦法就是使用default關鍵字。因此,在上面的代碼應該改成:線程

        public T Func<T>()
        {
            T t = default(T);
            return t;
        }

這樣若是它在運行時碰到的T是一個整型,那麼運行時會爲其賦值0;若是T在運行時是一個Person這樣的引用類型,則會爲其賦null值。3d

建議3六、使用FCL中的委託聲明

 要注意FCL中存在三類這樣的委託聲明,他們分別是:Action、Func、Predicate。尤爲是在他們的泛型版本出來之後,已經可以知足咱們在實際編碼過程當中的大部分須要。

這裏是以前一篇關於Action、Func、Predicate的有關介紹http://www.cnblogs.com/aehyok/p/3382291.html

除了Action、Func、Predicate外,FCL中還有用於標識特殊含義的委託聲明。如用於表示註冊事件方法的委託聲明:

public delegate void EventHandler(object sender,EventArgs e);

public delegate void EnentHandler<TEventArgs>(object sender,TEventArgs e);

表示線程的委託聲明:

public delegate void ThreadStart();

public delegate void ParameterizedThreadStart(object obj);

表示異步回調的委託聲明:

public delegate void AsyncCallback(IAsyncResult ar);

在FCL中沒一類委託聲明都表明一類特殊的用途,雖然可使用本身的委託聲明來代替,可是這樣作不只沒有必要,並且會讓代碼失去簡潔性和標準型。在咱們實現本身的委託聲明前,應該首先查看MSDN,確信有必要以後才這樣作。

建議3七、使用lambda表達式代替方法和匿名方法

首先咱們使用Action和Func來作一個簡單的小例子,控制檯應用程序代碼以下所示:

第一個版本

    class Program
    {
        static int Add(int i, int j)
        {
            return i + j;
        }

        static void Print(string message)
        {
            Console.WriteLine(message);
        }

        static void Main(string[] args)
        {
            Func<int, int, int> add = Add;
            Action<string> print = Print;
            print(add(4, 5).ToString());
            Console.ReadLine();
        }
    }

實際上要完成上面的功能,還有多種編碼方式,先來看一種最中規中矩的方式,同時也是最繁瑣的寫法:

第二個版本

    class Program
    {
        static int Add(int i, int j)
        {
            return i + j;
        }

        static void Print(string message)
        {
            Console.WriteLine(message);
        }

        static void Main(string[] args)
        {
            Func<int, int, int> add = new Func<int,int,int>(Add);
            Action<string> print =new Action<string>(Print);
            print(add(4, 5).ToString());
            Console.ReadLine();
        }
    }

其實也就是將第一個版本稍做調整。從上面的寫法中也能夠看出:Add方法和Print方法實際上都只有一條語句,所以,使用匿名方法也許是一種更好的選擇:

第三個版本

        static void Main(string[] args)
        {
            Func<int, int, int> add = new Func<int,int,int>(delegate(int i,int j)
                {
                    return i+j;
                });
            Action<string> print =new Action<string>(delegate(string message)
                {
                    Console.WriteLine(message);
                });
            print(add(4, 5).ToString());
            Console.ReadLine();
        }

使用匿名方法之後,咱們不須要在Main方法外部聲明兩個方法了,能夠直接在Main這個工做方法中完成全部的代碼編寫,並且不會影響代碼清晰性。實際上,全部代碼行數不超過3行的方法(條件是它不倍重用),咱們都建議採用這種方式來編寫。上面的版本繼續改進:

第四個版本

        static void Main(string[] args)
        {
            Func<int, int, int> add = delegate(int i,int j)
                {
                    return i+j;
                };
            Action<string> print =delegate(string message)
                {
                    Console.WriteLine(message);
                };
            print(add(4, 5).ToString());
            Console.ReadLine();
        }

以上代碼看上去更簡化了,不過,最終極的改進是使用lambda表達式:

第五個版本

        static void Main(string[] args)
        {
            Func<int, int, int> add = (x, y) => x + y;
            Action<string> print = (message) => Console.WriteLine(message);
            print(add(4, 5).ToString());
            Console.ReadLine();
        }

Lambda表達式操做符」=>「的左側是方法的參數,右側是方法體,其本質是匿名方法。實際上,通過編譯後Lambda表達式就是一個匿名方法。咱們應該在實際的編碼工做中熟練運用它,避免寫出繁瑣且不美觀的代碼。

 

相關文章
相關標籤/搜索