Lambda運算式方法
1.member => expression; //expression必須是語句運算式:方法、唯獨屬性、屬性、建構函數、完成項、索引子
2.Func<int, string, bool> isTooLong = (int x, string s) => s.Length > x;//輸入的全部要是明確的或全部都是隱含的
3. Lambda 無法用來建立運算式樹狀架構
4.非同步 Lambda 要在變數前面加async
5.C#7.0後可以使用元組
Func<(int, int, int), (int, int, int)> doubleThem = ns => (2 * ns.Item1//元組中的第一變數Item1為程式代稱, 2 * ns.Item2, 2 * ns.Item3);
6.Lambda 必須包含與委派類型相同數目的參數。
7.Lambda 中的每個輸入參數都必須能夠隱含轉換為其對應的委派參數。
8.Lambda 的傳回值 (如果有的話) 必須能夠隱含轉換為委派的傳回類型。
9.Lambda 運算式不能包含 goto、break 或 continue 陳述式
10.通常不會超過兩個或三個陳述式
11.Lambda 運算式無法直接從封入方法擷取 in、ref 或 out 參數
Action line = ()//沒有要傳值進去要打個括號 => Console.WriteLine();
Func<int, int, bool//最後都是傳回值> testForEquality = (x, y)要傳值進去變數打在括號內 => x == y;
//這三種都是一樣的只是簡化過程using System;(Func需要)
1.
Func<string, string> convertMethod = UppercaseString;string name = "Dakota";Console.WriteLine(convertMethod(name));string UppercaseString(string inputString){ return inputString.ToUpper();}
2.匿名方法
Func<string, string> convert = delegate(string s) { return s.ToUpper();};
3.Lambda運算式
Func<string, string> convert = s => s.ToUpper();
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class Exercisc : MonoBehaviour
{
public int My_Money=5000;
void Start()
{
Func<string, int, int> Buy = (x, y) =>
{
Debug.Log("買" + x);
My_Money -= y;
return My_Money;
};
Action<string> Description = (x) => {
Shop();
Debug.Log("想要買"+x);
Debug.Log(Shopee(x));
};
Description("香蕉");
Description("椰子");
Debug.Log("剩下" + Buy("蘋果", 20));
Debug.Log("剩下" + Buy("榴槤", 170));
//結果
進入商店
想要買香蕉
香蕉賣完了(隨機的)
進入商店
想要買椰子
椰子賣完了
買蘋果
剩下980
買榴槤
剩下810
}
public void Shop()
{
Debug.Log("進入商店");
}
public string Shopee(string name)
{
int x = UnityEngine.Random.Range(0, 2);
if (x==0)
{
return name + "賣完了";
}
return name + "現在還有庫存";
}
}
Aggregate
numbers//陣列.Aggregate(1//初始值不一定要是int, (int interim//用初始值當累積值變數,
int x//陣列數值) => interim*x//這邊會執行陣列格多少=多少次,如int [] numbers={1,2,3,4}執行4次然後每一次傳回
interim值所以最後傳回interim會是24);
委派(Delegate)
功用:委派可以用來將方法當做引數傳遞給其他方法,也可以多載方法來執行//方法可以是靜態或執行個體方法
1.委派類型是密封的,不能作為其他類型的衍生來源,且不可能從 Delegate 衍生自訂類別
2.可讓方法以參數方式接受委派,並於稍後呼叫委派
3.可以直接從類別取得靜態方法,如果不是靜態方法要先具現化類別才能抓取
4.可以使用+=增加方法或-=移除方法,多點傳送委派和多點傳送委派也可以使用+=和-=(多點傳送委派)
5.傳到委派的方法要和委派一樣如:Delegate int del() 只能帶入int 方法()
6.如果是多點傳送委派有傳回值,會傳回的是最後一個方法所傳回的值,前面的不會傳回
7.不要同時存在2個以上的Delegate void del_1() Delegate void del_2() 會導致編譯錯誤但是這樣是可以的Delegate void del_1() Delegate void del_2(int x)
8.假如Delegate void del_1(B x)和Delegate void del_2(C y)它們的 B和C的基底類別是A
當有基底類別A的方法時可以+=到del_1和del_2//就是反變數
9.在泛型委派中啟用隱含轉換,您必須使用 in 或 out 關鍵字,明確宣告委派中的泛型參數為 Covariant 或 Contravariant。
//public delegate T SampleGenericDelegate <out T>();
SampleGenericDelegate<String> 無法明確地轉換成 SampleGenericDelegate<Object>,雖然 String 繼承 Object。 您可以使用 out 關鍵字標記泛型參數 T,修正這個問題。
10.如果您使用唯一的差異支援來比對方法簽章與委派型別,請不要使用 in 和 out 關鍵字,因為您會發現,有時候您會使用相同的 lambda 運算式或方法具現化委派,但無法將一個委派指派給另一個。
11.out 關鍵字將泛型委派中的泛型型別參數宣告為 Covariant
in 關鍵字將泛型委派中的泛型型別參數宣告為 Contravariant
Covariant 型別僅可用為方法傳回型別
Contravariant 型別僅可用為方法引數的型別,不能用為方法傳回型別
12.具有 Covariant 或 Contravariant 泛型型別參數,它可以稱之為「Variant 泛型委派」
13.不應該組合 Variant 委派。 Combine 方法不支援 Variant 委派轉換,且委派的類型必須完全一致
14.Func<T//變數,TResult//傳回變數> 和Delegate TResult//傳回變數 del_1(T//變數 x)是一樣的
Action<T>和Delegate void del_1(T//變數 x)是一樣的
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Exercisc : MonoBehaviour
{
public class Product
{
public string Name;
public int Price;
public Product(string name,int price)
{
Name = name;
Price = price;
}
}
public class Product_Descripion : Product
{
public string Descripion;
public Product_Descripion(string name, int price,string descripion) : base(name, price)
{
Name = name;
Price = price;
Descripion = descripion;
}
}
public int My_Money = 1000;
public delegate int Del_1(Product pro);
public delegate void Del_2(Product_Descripion name);
void Start()
{
Product product_A = new Product("麵包", 20);
Product product_B = new Product("酒", 100);
Product product_C = new Product("壽司", 250);
Product product_D = new Product("蘋果", 10);
Product product_E = new Product("柚子", 70);
Product_Descripion Product_Descripion_A = new Product_Descripion(product_A.Name, product_A.Price,"包有紅豆");
Product_Descripion Product_Descripion_B = new Product_Descripion(product_B.Name, product_B.Price,"釀造10年之久");
Product_Descripion Product_Descripion_C = new Product_Descripion(product_C.Name, product_C.Price,"使用越南米");
Product_Descripion Product_Descripion_D = new Product_Descripion(product_D.Name, product_D.Price,"日本空運來的");
Product_Descripion Product_Descripion_E = new Product_Descripion(product_E.Name, product_E.Price,"民間小農自產");
Del_1 Buy_A = Buy;
Del_1 Sell_A = Sell;
Del_1 All_A = Buy;
All_A += Sell;
Del_2 Des_A = Descripion_obj;
Del_2 Des_All = Descripion_obj;
Des_All +=Product_Name;
Des_All -= Descripion_obj;
Debug.Log("剩餘"+ Buy_A(product_A));
Debug.Log("剩餘"+Buy_A(Product_Descripion_B));
Debug.Log("~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
Debug.Log("剩餘"+Sell_A(product_D));
Debug.Log("剩餘"+Sell_A(product_E));
Debug.Log("~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
Debug.Log("剩餘" + All_A(product_E));
Debug.Log("~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
Des_A(Product_Descripion_A);
Des_A(Product_Descripion_B);
Debug.Log("~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
Des_All(Product_Descripion_A);
Des_All(Product_Descripion_B);
Debug.Log("使用共變數~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
product_B = Product_Descripion_A;
Debug.Log("剩餘"+Buy_A(product_B));
//結果
購買麵包
剩餘980
購買酒
剩餘880
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
賣出蘋果
剩餘890
賣出柚子
剩餘960
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
購買柚子
賣出柚子
剩餘960
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
麵包特色包有紅豆
酒特色釀造10年之久
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
麵包
酒
使用共變數~~~~~~~~~~~~~~~~~~~~~~~~~~~~
購買麵包
剩餘940
}
public int Buy(Product pro)
{
Debug.Log("購買"+pro.Name);
return My_Money-=pro.Price;
}
public int Sell(Product pro)
{
Debug.Log("賣出"+pro.Name);
return My_Money += pro.Price;
}
public void Descripion_obj(Product_Descripion name)
{
Debug.Log(name.Name + "特色" + name.Descripion);
}
public void Product_Name(Product_Descripion name)
{
Debug.Log(name.Name);
}
}