c#基礎(chǔ)知識(shí)---委托,匿名函數(shù),lambda
前言:
C# 中的委托(Delegate)類(lèi)似于 C 或 C++ 中函數(shù)的指針。委托是存有對(duì)某個(gè)方法的引用的一種引用類(lèi)型變量。引用可在運(yùn)行時(shí)被改變。委托(Delegate)特別用于實(shí)現(xiàn)事件和回調(diào)方法。所有的委托都派生自 System.Delegate 類(lèi)。把一個(gè)方法當(dāng)作參數(shù)傳遞,讓其它方法進(jìn)行調(diào)用執(zhí)行。
1.委托的聲明
委托聲明決定了可由該委托引用的方法。委托可指向一個(gè)與其具有相同標(biāo)簽的方法。
1.1.delegate
1.1.1. 0-23個(gè)參數(shù),可以有返回值也可以沒(méi)有返回值
public delegate int MyDelegateEventHandler (string parm);
注:(1).此委托指向的方法必須是參數(shù)為string類(lèi)型,返回類(lèi)型為int類(lèi)型的。其他聲明類(lèi)比所得。
(2).EventHandler是c# 命名規(guī)范,當(dāng)然我理解規(guī)范就是可以隨意啦。
(3).委托調(diào)用時(shí)必須判斷是否為null不然會(huì)報(bào)異常
(4).事件也是一種委托
1.1.2.委托的調(diào)用
MyDelegateEventHandler fun=new MyDelegateEventHandler(method); or MyDelegateEventHandler fun=method; // fun不為空,則調(diào)用回調(diào)方法 if (fun!= null) { fun(val); } //fun?.Invoke(val); 簡(jiǎn)化版本調(diào)用
1.1.3.委托的多播
每個(gè)委托都只包含一個(gè)方法調(diào)用,如果調(diào)用多個(gè)方法,就需要多次顯示調(diào)用這個(gè)委托。如果同一個(gè)委托調(diào)用多個(gè)方法,我們就可以用多播委托
public delegate void MyDelegate (); public voidMyMethod() { //# } public void MyMethod1() { //# } public void MyMethod2() { //# } MyDelegateEnventHander myDelegate; myDelegate=new MyDelegateEventHander(MyMethod); myDelegate+=new MyDelegateEventHander(MyMethod1); ........... //調(diào)用 myDelegate();
注:
1.委托對(duì)象可使用 "+" 運(yùn)算符進(jìn)行合并;
2."-" 運(yùn)算符可用于從合并的委托中移除組件委托;
3.委托指定方法類(lèi)型必須一致;
4.返回類(lèi)型一般為void,但非必須;
5.GetInvocationList獲取委托索引
if (MyDelegate != null) System.Delegate[] dels = MyDelegate .GetInvocationList(); for (int i = 0; i < dels.Length; i++) { MyDelegate -= dels[i] as MethodDelegate; }
以上是利用GetInvocationList獲取委托索引的一個(gè)簡(jiǎn)單應(yīng)用。
1.2.Action
Action至少0個(gè)參數(shù),至多16個(gè)參數(shù),無(wú)返回值。
Action 表示無(wú)參,無(wú)返回值的委托 Action<int,string> 表示有傳入?yún)?shù)int,string無(wú)返回值的委托 Action<int,string,bool> 表示有傳入?yún)?shù)int,string,bool無(wú)返回值的委托 Action<int,int,int,int> 表示有傳入4個(gè)int型參數(shù),無(wú)返回值的委托
public void Test<T>(Action<T> action,T p) { action(p); }
1.3.Func
Func至少0個(gè)參數(shù),至多16個(gè)參數(shù),根據(jù)返回值泛型返回。必須有返回值,不可void
Func是無(wú)返回值的泛型委托 Func<int> 表示無(wú)參,返回值為int的委托 Func<object,string,int> 表示傳入?yún)?shù)為object, string 返回值為int的委托 Func<object,string,int> 表示傳入?yún)?shù)為object, string 返回值為int的委托 Func<T1,T2,,T3,int> 表示傳入?yún)?shù)為T(mén)1,T2,,T3(泛型)返回值為int的委托
1.4.predicate
1.predicate 是返回bool型的泛型委托;
2.predicate<int> 表示傳入?yún)?shù)為int 返回bool的委托;
3.Predicate有且只有一個(gè)參數(shù),返回值固定為bool;
public delegate bool Predicate<T> (T obj)
2.委托的實(shí)例化
2.1.delegate
public delegate int MyDelegateEventHandler (string parm) public int MyMethod(string parm) { //# } MyDelegateEventHandler MyDelegate=new MyDelegateEventHandler(MyMethod)
注:委托實(shí)例化的時(shí)候,委托對(duì)象必須使用 new 關(guān)鍵字來(lái)創(chuàng)建,且與一個(gè)特定的方法有關(guān)。委托參數(shù)中的方法不含參數(shù)。
2.2.Action的使用
public void Test<T>(Action<T> action, T p) { action(p); } private void Action(string s) { # } //調(diào)用 Test<string>(Action,"wyl");
2.3.Func的使用
public int Test<T1, T2>(Func<T1, T2, int> func, T1 a, T2 b) { return func(a, b); } private int Fun(int a, int b) { # } //調(diào)用 Test<int,int>(Fun,100,200)
2.4 委托實(shí)現(xiàn)冒泡排序
//定義對(duì)象 class Student { public string Name { get; private set; } public decimal Scores{ get; private set; } public Student(string name, decimal scores) { this.Name = name; this.Scores= scores; } public override string ToString() { return string.Format("{0},{1:C}",Name,Scores); } public static bool CompareScores(Student e1,Student e2) { return e1.Scores< e2.Scores; } } //利用委托實(shí)現(xiàn)冒泡 class BubbleScores { public static void Sort<T>(IList<T> sortArray, Func<T, T, bool> comparison) { bool swapped = true; do { swapped = false; for (int i = 0; i < sortArray.Count - 1; i++) { if (comparison(sortArray[i + 1], sortArray[i])) { T temp = sortArray[i]; sortArray[i] = sortArray[i + 1]; sortArray[i + 1] = temp; swapped = true; } } } while (swapped); } } //調(diào)用 Student[] students={new Student("wyl", 100),#}; BubbleSorter.Sort(students, Student.CompareScores); foreach(var student in students) Console.WriteLine(student);
3.匿名函數(shù)與lambda
3.1什么是匿名函數(shù)
匿名函數(shù)是一個(gè)“內(nèi)聯(lián)”語(yǔ)句或表達(dá)式,可在需要委托類(lèi)型的任何地方使用。
可以使用匿名函數(shù)來(lái)初始化命名委托(無(wú)需取名字的委托),或傳遞命名委托(而不是命名委托類(lèi)型,傳遞一個(gè)方法塊,而不是委托類(lèi)型)[callback的方式]作為方法參數(shù)。
MyDelegate funDelegate = delegate(string s) { Console.WriteLine(s); }; funDelegate ("this is anonymous delegate");
3.2.lambda
lambda表達(dá)式實(shí)際上是一個(gè)匿名函數(shù)。編譯器在看到lambda之后會(huì)在類(lèi)中自動(dòng)定義一個(gè)新的私有方法。lambda必須匹配委托!其中l(wèi)ambda是從c#3.0后引用的
lambda的語(yǔ)法:
參數(shù) => 方法體。
=>左邊是要傳入的參數(shù),本例中是傳入一個(gè)Int類(lèi)型的變量,=>右邊是具體的代碼。
//如果不傳遞參數(shù): ()=>Console.WriteLine("Hello World!") //傳遞一個(gè)參數(shù): (int n)=>Console.WriteLine(n.ToString()) //或者去掉()和int 編譯器會(huì)自己推斷類(lèi)型: n=>Console.WriteLine(n.ToString()) //傳遞多個(gè)參數(shù): (int n ,int m)=>Console.WriteLine(n+m) //或者編譯器自己推斷類(lèi)型: (n , m)=>Console.WriteLine(m+n)
4.綜上:
1.委托類(lèi)似于 C++ 函數(shù)指針。
2.委托允許將方法作為參數(shù)進(jìn)行傳遞。
3.委托可用于定義回調(diào)方法。
4.委托可以鏈接在一起;多播。
5.方法不必與委托簽名完全匹配。
以上就是c#基礎(chǔ)知識(shí)---委托,匿名函數(shù),lambda的詳細(xì)內(nèi)容,更多關(guān)于c# 委托,匿名函數(shù),lambda的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
unity實(shí)現(xiàn)場(chǎng)景跳轉(zhuǎn)
這篇文章主要為大家詳細(xì)介紹了unity實(shí)現(xiàn)場(chǎng)景跳轉(zhuǎn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-04-04C#實(shí)現(xiàn)銷(xiāo)售管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C#實(shí)現(xiàn)銷(xiāo)售管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-06-06WPF中下拉框可作選擇項(xiàng)也可以作為只讀文本框使用的方法
這篇文章主要給大家介紹了關(guān)于WPF中下拉框可以選擇項(xiàng)也可以作為只讀文本框使用的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2023-02-02C#使用foreach語(yǔ)句遍歷二維數(shù)組的方法
這篇文章主要介紹了C#使用foreach語(yǔ)句遍歷二維數(shù)組的方法,實(shí)例分析了C#遍歷數(shù)組的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-04-04WPF自定義控件實(shí)現(xiàn)ItemsControl魚(yú)眼效果
這篇文章主要為大家詳細(xì)介紹了WPF如何通過(guò)自定義控件實(shí)現(xiàn)ItemsControl魚(yú)眼效果,文中的示例代碼講解詳細(xì),需要的可以參考一下2024-01-01