一、語法特性 1. using引入類型 using關鍵字在.NET中有兩個意義,這裡是指引入命名空間。要是支持using類型會帶來很大方便,比如: using System.Runtime.InteropServices.Marshall; //可以直接調用Marshall類的靜態方法和屬性 using List<string>= StringList; //寫起來不用再打<> 2. 變量命名空間 有時候,處理業務很復雜,即使在一個不能再分割的處理單元中也有許多變量,命名和組織成了一個頭疼的問題,將這些封裝成類又不值得。如果可以在聲明變量或字段時定義命名空間,這個煩惱就能解決: class ProductUtil{ namespace Price { float old; float New; float standard; } float GetPrice(){ float Price.discount; //聲明折扣 //計算價格... return Price.New; } } 命名空間可以在方法內,也可以在類型內。聲明命空間後,可以單獨聲明一個變量。 3. 用out聲明變量. 有點經驗的開發者會經常用Try-Parse避免產生異常,一般TryParse、TryGet這類方法都把結果傳給用out聲明的參數中,我總是在想,為什麼這個參數要先聲明呢? int value; //這個聲明完全可以去掉,看起來不爽 if (int.TryParse(s, out value)) { Console.WriteLine(value); } 4. 省略屬性字段 C# 3.0推出了簡化屬性的方式:public string Text { get;set; }。但還不徹底,對於get set內部有一定處理邏輯的,無法省略字段。如果可以用一個關鍵字代替字段,將使代碼更整潔。 我覺得用default在屬性內表示字段不錯,如果在內部其他方法中要直接訪問此字段(應該很謹慎地),可以用default(this.Text),好像有點麻煩,但這種情況很少,這樣用會更醒目。 5. 能做就做 要說最煩的,還是這種判斷代碼 if(list != null && list.Count > 0){ return list.Last(); } 很多時候,根本無需處理list為null或空的情況,如果上面的代碼能可以寫成這樣,必然很受歡迎: return list.Last()??; 從此以後,我們可以唱:兄弟你大膽地往下寫喲~~,別怕異常~~ 6. 帶參構造函數約束 泛型約束只能聲明無參構造函數,這種限制沒任何道理。應可以像下面這樣。 public class MyClass<T> where T : class, new(int) { ... } 或者不限制構造函數的參數: public class MyClass<T> where T : class, new { ... } 如果調用了不兼容的構造函數,IDE完全可以在編譯時檢查出來。 7. case可跟表達式 剛學編程接觸switch case時,就很不解case後面只能跟常量的限制。這其實應該是個bug,包括其他語言。 8. 擴展屬性 當時擴展方法推出的時候,為什麼沒有擴展屬性呢?我知道肯定有某種理由,但這個真可以有。 9. 綁定運算符 對於兩個類實例 A=B 將使AB指向同一個引用,若隨後B引用變化了,對A沒有影響。許多初學者搞不清=運算符的作用,以為B變化,A也隨之變化。 其實這種特性是C#一直都欠缺的,如果我們可以讓 A==B 實現A和B的綁定(左邊可以是表達式),那許多工作就輕松了。 要考慮GC的問題,如果A未被回收,B也不能被回收。 10. 項目引用Native dll 如今要調用C/C++的程序集,必須查好參數,轉化類型,再像這種方式聲明: [DllImport("User32.dll", CharSet = CharSet.Unicode)] public static extern int MessageBox(int h, string m, string c, int type); 為什麼不能像引用.NET dll那樣引用C/C++寫的dll呢,或者像Service Reference那樣,增加一個Native Reference的目錄,自動生成代理類。 11. Fluent語法 利用語法糖,希望能夠大幅減少關鍵字使用,比如對於(int)value, value as string都可以用ToSomeType()表示。若調用構造函數,可以省略new關鍵字。 在使用第一條using聲明調用靜態方法的類後,可以將靜態方法作為任一參數的擴展方法。 using String; static void SortDates(string dates) { var lstDates = dates.Split(',').Select(d=>d.ToDateTime()); //ToDateTime()相當於(DateTime) var endDate = DateTime(lstDates.Max().Year, 12 ,31); //省略new dates = lstDates.OrderBy(d=>d).Join(","); //String.Join方法變擴展方法 } 12. 全局性配置 這其實是由Visual Studio實現的功能。如果實現擴展屬性,直接調用類靜態方法,會導致自動提示裡擁擠不堪,讓便利性打折扣。應該可以在項目屬性裡配置,導入一個配置模板,默認隱藏掉那些不常用的成員,比如所有類型都甩不掉的Equals/ReferenceEquals/GetHashCode。這個模板還可以用using為類型起別名,就不必在每個文件中一一聲明了。 這樣C#關鍵字會大大減少,還可以定制更加符合個人或團隊習慣的命名。 二、動態支持 C#的反射雖然很完善了,但性能還是差,並且相當不友好。如果要運行時修改代碼,即使用最先進的Lamda Expression,還有第三方框架MonoCecil都很麻煩,更別說用Emit和Code Generator。所以C#基本上還是一門靜態語言,這樣滿足諸如AOP這種高擴展性開發需求,仍然十分吃力。 我們早對一個基於項目的元數據框架望眼欲穿了,徹底解放被元數據和動態代碼束縛已久的生產力。 首先,要增強T4模板,使之更方便地引用自身和第三方程序集。實現像Razor那種語法支持應該不過分吧。使用好T4模板,可以大大提高代碼重用性(對AVL樹和紅黑樹的個人理解),還有避免元數據操作(性能相差7千倍的ToString方法)。 對於一個項目,應該提供一個編譯選項,可以自動生成強類型的元數據程序集。比如MVC中,可以這樣用: using MySite.Metadata; //引入自動生成的元數據程序集 namespace MySite.Controllers { public class HomeController : Controller { public ActionResult Home() { if (!User.Identity.IsAuthenticated) return Views.Login; //Views自動生成,取代 View("Login") return View(); } } } 假設有一個Person類,有Name/Sex/Birthday三個屬性,我們希望這樣運行時加一個Age屬性: MyProject.Metadata.Class.Person.CreateProperty("Age", p=> (DateTime.Now - p.Birthday).Year); 調用這些動態屬性時,只要用dynamc特性即可(當前這個特性應用很有限),最好能為dynamic類型提供一個類似JQuery的attr函數。 如果能實現JS的eval函數的功能就更好了,那樣C#代碼也許會變得我都不認識了。 三、設計面向 編程語言發展已經超過半個世紀了,先是面向變量的匯編語言,高級語言出現後,從Pascal/C語言面向過程和變量,到C++以後的面向對象。 C#和Java只是語言特性上有大幅改進,設計思想並沒有飛躍。 C#作為最為先進的編程語言,反映了當前語言發展的瓶頸。要有所突破,必須要有新的設計思想,把面向粒度提高到新的層次。 個人分析後認為,未來C#或C#的後繼者,會向三個方向發展: 1. 面向集合 未來編程語言遇到的業務邏輯將更復雜,對集合處理是業務邏輯的核心內容。LINQ使C#走在業界的前列,然而還有許多問題。 由於歷史原因,集合類型太多太亂。支持泛型是必須,我們需要根據可變性、排序性、Hash特性、並發要求等,使用一致的高性能集合類型。這些集合類能夠靈活轉化,智能地處理擴容、復制等底層操作,且LINQ那樣無法跨程序域傳遞的限制。這需要框架和CLR雙重支持。 2. 面向並發 這個是很自然的方向,除非出現光、生物、量子計算技術的突破,不然半導體電路處理器單核極限愈來愈難突破,多核趨勢愈演愈烈。未來的編程語言,並發支持必須融入其底層。 還是拿Node.js來說,已經初具此特性,其對IO的訪問全部非阻塞的,是從底層支持的異步操作。 對於C#來說,就不只是框架上修修補補,而是CLR的全面支持。async和await出現是個很好的苗頭,期待看到更多這樣的發展。 3. 面向任務 Node.js它通過事件輪詢(event loop)來實現並行操作,這只能處理最簡單地多任務同步。要實現真正的並發語言,並滿足日益復雜的業務邏輯處理,必須對並發的單元-任務進行有力的支持。 .NET對任務有了System.Threading.Tasks下一系列類的支持,但這只是開始。我們需要動態地創建、分解、修改、取消任務,需要方便地獲取和控制任務的狀態,管理超時和資源,統計任務效率,處理異常。 前面的路還很遠,很長,也一定很精彩。以後我還會繼續研究這些方向。