日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

背后的故事之 - 快乐的Lambda表达式(二)

發布時間:2023/12/10 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 背后的故事之 - 快乐的Lambda表达式(二) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

快樂的Lambda表達式

  上一篇?背后的故事之 - 快樂的Lambda表達式(一)我們由淺入深的分析了一下Lambda表達式。知道了它和委托以及普通方法的區別,并且通過測試對比他們之間的性能,然后我們通過IL代碼深入了解了Lambda表達式,以及介紹了如何在.NET中用Lambda表達式來實現JavaScript中流行的一些模式。

  今天,我們接著來看Lambda表達式在.NET中還有哪些新鮮的玩法。

Lambda表達式玩轉多態

  Lambda如何實現多態?我們用抽象類和虛方法了,為什么還要用Lambda這個玩意?且看下面的代碼:

class MyBaseClass {public Action SomeAction { get; protected set; }public MyBaseClass(){SomeAction = () =>{//Do something!};} }class MyInheritedClass : MyBaseClass {public MyInheritedClass(){SomeAction = () => {//Do something different!};} }

  我們的基類不是抽象類,也沒有虛方法,但是把屬性通過委托的方式暴露出來,然后在子類中重新為我們的SomeAction賦予一個新的表達式。這就是我們實現多態的過程,當然父類中的SomeAction的set有protected的保護級別,不然就會被外部隨易修改了。但是這還不完美,父類的SomeAction在子類中被覆蓋之后,我們徹底訪問不到它了,要知道真實情況是我們可以通過base來訪問父類原來的方法的。接下來就是實現這個了:

class MyBaseClass {public Action SomeAction { get; private set; }Stack<Action> previousActions;protected void AddSomeAction(Action newMethod){previousActions.Push(SomeAction);SomeAction = newMethod;}protected void RemoveSomeAction(){if(previousActions.Count == 0)return;SomeAction = previousActions.Pop();}public MyBaseClass(){previousActions = new Stack<Action>();SomeAction = () => {//Do something!};} }

  上面的代碼中,我們通過AddSomeAction來實現覆蓋的同時,將原來的方法保存在previousActions中。這樣我們就可以保持兩者同時存在了。

  大家知道子類是不能覆蓋父類的靜態方法的,但是假設我們想實現靜態方法的覆蓋呢?

void Main() {var mother = HotDaughter.Activator().Message;//mother = "I am the mother"var create = new HotDaughter();var daughter = HotDaughter.Activator().Message;//daughter = "I am the daughter" }class CoolMother {public static Func<CoolMother> Activator { get; protected set; }//We are only doing this to avoid NULL references!static CoolMother(){Activator = () => new CoolMother();}public CoolMother(){//Message of every motherMessage = "I am the mother";}public string Message { get; protected set; } }class HotDaughter : CoolMother {public HotDaughter(){//Once this constructor has been "touched" we set the Activator ...Activator = () => new HotDaughter();//Message of every daughterMessage = "I am the daughter";} }

  這里還是利用了將Lambda表達式作為屬性,可以隨時重新賦值的特點。當然這只是一個簡單的示例,真實項目中并不建議大家這么去做。?

方法字典

  實際上這個模式我們在上一篇的返回方法中已經講到了,只是沒有這樣一個名字而已,就算是一個總結吧。故事是這樣的,你是不是經常會寫到switch-case語句的時候覺得不夠優雅?但是你又不想去整個什么工廠模式或者策略模式,那怎么樣讓你的代碼看起來高級一點呢?

public Action GetFinalizer(string input) {switch{case "random":return () => { /* ... */ };case "dynamic":return () => { /* ... */ };default:return () => { /* ... */ };} }//-------------------變身之后----------------------- Dictionary<string, Action> finalizers;public void BuildFinalizers() {finalizers = new Dictionary<string, Action>();finalizers.Add("random", () => { /* ... */ });finalizers.Add("dynamic", () => { /* ... */ }); } public Action GetFinalizer(string input) {if(finalizers.ContainsKey(input))return finalizers[input];return () => { /* ... */ }; }

  好像看起來是不一樣了,有那么一點味道。但是一想是所有的方法都要放到那個BuildFinalizers里面,這種組織方法實在是難以接受,我們來學學插件開發的方式,讓它自己去找所有我們需要的方法。

static Dictionary<string, Action> finalizers;// 在靜態的構造函數用調用這個方法 public static void BuildFinalizers() {finalizers = new Dictionary<string, Action>();// 獲得當前運行程序集下所有的類型var types = Assembly.GetExecutingAssembly().GetTypes();foreach(var type in types){// 檢查類型,我們可以提前定義接口或抽象類if(type.IsSubclassOf(typeof(MyMotherClass))){// 獲得默認無參構造函數var m = type.GetConstructor(Type.EmptyTypes);// 調用這個默認的無參構造函數if(m != null){var instance = m.Invoke(null) as MyMotherClass;var name = type.Name.Remove("Mother");var method = instance.MyMethod;finalizers.Add(name, method);}}} } public Action GetFinalizer(string input) {if(finalizers.ContainsKey(input))return finalizers[input];return () => { /* ... */ }; }

  如果要實現插件化的話,我們不光要能夠加載本程序集下的方法,還要能隨時甚至運行時去加載外部的方法,請繼續往下看:

internal static void BuildInitialFinalizers() {finalizers = new Dictionary<string, Action>();LoadPlugin(Assembly.GetExecutingAssembly()); }public static void LoadPlugin(Assembly assembly) {var types = assembly.GetTypes();foreach(var type in types){if(type.IsSubclassOf(typeof(MyMotherClass))){var m = type.GetConstructor(Type.EmptyTypes);if(m != null){var instance = m.Invoke(null) as MyMotherClass;var name = type.Name.Remove("Mother");var method = instance.MyMethod;finalizers.Add(name, method);}}} }

  現在,我們就可以用這個方法,給它指定程序集去加載我們需要的東西了。

  最后留給大家一個問題,我們能寫遞歸表達式么?下面的方法如果用表達式如何寫呢?

int factorial(int n) {if(n == 0)return 1;elsereturn n * factorial(n - 1); }

  

轉載于:https://www.cnblogs.com/jesse2013/p/happylambda-part2.html

總結

以上是生活随笔為你收集整理的背后的故事之 - 快乐的Lambda表达式(二)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。