創作內容

1 GP

Unity C# Lambda和Delegate 功能說明

作者:蝦米coco│2020-05-19 02:03:54│巴幣:2│人氣:1659
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 運算式不能包含 gotobreakcontinue 陳述式
10.通常不會超過兩個或三個陳述式
11.Lambda 運算式無法直接從封入方法擷取 inrefout 參數

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);
    }
}

引用網址:https://home.gamer.com.tw/TrackBack.php?sn=4787290
All rights reserved. 版權所有,保留一切權利

相關創作

留言共 1 篇留言

樂小呈
[e26]

05-19 08:53

蝦米coco
[e28]05-19 10:16
我要留言提醒:您尚未登入,請先登入再留言

1喜歡★pk123634 可決定是否刪除您的留言,請勿發表違反站規文字。

前一篇:Unity C# 非同步... 後一篇:石頭一顆...

追蹤私訊切換新版閱覽

作品資料夾

ilove487
小屋小說連載超過 250 萬字!!看更多我要大聲說昨天11:59


face基於日前微軟官方表示 Internet Explorer 不再支援新的網路標準,可能無法使用新的應用程式來呈現網站內容,在瀏覽器支援度及網站安全性的雙重考量下,為了讓巴友們有更好的使用體驗,巴哈姆特即將於 2019年9月2日 停止支援 Internet Explorer 瀏覽器的頁面呈現和功能。
屆時建議您使用下述瀏覽器來瀏覽巴哈姆特:
。Google Chrome(推薦)
。Mozilla Firefox
。Microsoft Edge(Windows10以上的作業系統版本才可使用)

face我們了解您不想看到廣告的心情⋯ 若您願意支持巴哈姆特永續經營,請將 gamer.com.tw 加入廣告阻擋工具的白名單中,謝謝 !【教學】