簡體   English   中英

C#中的委托與行動有什么區別

[英]What is the difference between Delegate & Action in C#

如果我搜索過,我肯定會得到一個顯示什么是委托和行動的例子。 我已經閱讀了基本書籍,給出了代表的例子。

但我想知道的是它們在現實世界中的應用。 請不要給Hello World示例或動物類它們太基本了

例如:

  1. 它們之間有什么區別
  2. 何時使用委托或行動
  3. 何時不使用代表或行動
  4. 當他們可以過度殺戮

Action Delegate 它的定義如下:

public delegate void Action();

您可以創建自己的委托類型,類似於創建抽象方法的方式; 你寫簽名但沒有實現。 然后,您可以通過引用方法來創建這些委托的實例。

class Program
{
    public static void FooMethod()
    {
        Console.WriteLine("Called foo");
    }

    static void Main()
    {
        Action foo = FooMethod; // foo now references FooMethod()
        foo(); // outputs "Called foo"
    }
}

定義委托時,實質上是定義方法的簽名(返回類型和參數)。

Action是一個已經定義的委托(void return和no args)。

public delegate void Action()

你可以去定義並親自看看。 或者在文檔中。 http://msdn.microsoft.com/en-us/library/system.action.aspx

當我正在尋找的方法的簽名與支持的簽名匹配時,我幾乎總是使用現有的通用委托(其中一個操作是一個)。 使用泛型代理的一個好處是它們是眾所周知的。 大多數開發人員都知道動作無效/無效。 如果我要定義自己的Action版本,每個人都需要查找它的簽名,我只是復制了已經存在的東西。

例如......由於void / void方法的目的只能用於變異,因此動作恰好有點罕見。 Func很常見(也是通用委托)。 在整個框架中都有它的用法示例,特別是在linq中。 比如看看。的地方。 http://msdn.microsoft.com/en-us/library/bb534803.aspx 它是一個Func意味着它將您正在處理的集合類型的元素作為參數並返回一個bool。 在具有Func返回true的where語句的上下文中,意味着將其包含在結果中,反之亦然。

public static IEnumerable<TSource> Where<TSource>(
    this IEnumerable<TSource> source,
    Func<TSource, bool> predicate
)

由於Kenneth&Siege已經指出代碼和MSDN,我將嘗試填寫現實世界的例子。

考慮一個定義“移動”的委托。

現實世界中的“行動”代表將是“跑步”或“行走”。 您不關心您移動的速度,您采取的路線或報告移動所需的時間。

例如,非Action代理可以定義您運行的速度並返回完成它所花費的時間。

public delegate void MoveAction();
public delegate int MoveDelegate(int speed);

擴展圍攻的例子..

class Program
{
    public static void Run()
    {
        Console.WriteLine("Running");
    }

    public static int RunAtSpeed(int speed)
    {
         // logic to run @ speed and return time
         Console.WriteLine("Running @ {0}", speed); 
         return 10;
    }

    public static int WalkAtSpeed(int speed)
    {
         // logic to walk @ speed and return time
         Console.WriteLine("Walking @ {0}", speed); 
         return 20;
    }

    static void Main()
    {
        Action foo = Run; 
        foo(); 

        MoveDelegate run = RunAtSpeed;
        int result1 = run(5);

        MoveDelegate walk = WalkAtSpeed;
        int result2 = walk(1);
    }
}

什么是Action:很簡單的Action,Func <>,謂詞都屬於委托類型。

我們為什么需要Action: Action在很多情況下封裝了不同數量的參數和不同類型的返回類型,足以滿足應用程序開發的需要。 這些在System命名空間中提供。 您可以自由創建自己的代理。

請注意,有17種不同類型的Action和Func,每種類型都有0到16個參數化通用參數。

操作始終沒有返回值。 Func具有單個參數化泛型返回類型。

恕我直言,謂詞委托不需要被定義為它真正等同於Func,它接受一個arg並返回bool。

已經反復請求的真實世界示例代碼已在“Console.WriteLine”用戶的早期答案中提供。

至於為什么提供它,從我的理解,行動是一種方法來節省定義自己的新代表。 由於它是特定簽名類型的預定義委托,因此可以節省為每個預期目的創建不同委托的麻煩。 您只需使用預定義的Action委托指向您的方法並運行它們。 Func委托的情況也是如此。

真的更方便,而不是實際的新功能。 幫助您保持代碼簡短易懂,減少麻煩。

至於你的觀點問題,

  1. 它們之間有什么區別

沒有不同。 Action是一個預定義的委托,旨在為您省去重復定義新委托的麻煩。

  1. 何時使用委托或行動

通常,委托(和操作)用於需要具有表驅動功能的位置。 即,可能是對應於某些特定要求的方法的字典。 請注意,在此處使用Action可以輕松更改所調用的最終方法,以動態指向其他方法(可能基於用戶選擇的某些設置?)


class Program
{
    static void Main()
    {
     Dictionary<string, Action> dict = new Dictionary<string, Action>();
     dict["loadFile"] = new Action(LoadFile);
     dict["saveFile"] = new Action(SaveFile);

     dict["loadFile"].Invoke();
     dict["saveFile"].Invoke();
    }

    static void SaveFile()
    {
     Console.WriteLine("File saved!");
    }

    static void LoadFile()
    {
     Console.WriteLine("Loading File...");
    }
}

另一種典型用法是回調方法。 示例是您使用BubbleSort類的地方,將比較器方法作為委托傳遞給類,BubbleSort類將使用它來允許您的代碼定義比較邏輯,同時處理其他所有事情。 這也可以從您已啟動的線程中使用,並且線程在需要將某些中間操作通知您的代碼時調用該委托。

你可以參考這篇SO帖子,看看上面的一個很好的例子。 https://stackoverflow.com/a/3794229/1336068

  1. 何時不使用代表或行動

我認為在情況需要時不使用它們的唯一原因是,如果你的代表將在短時間內被召喚數百萬次。 涉及到一些輕微的開銷,如果這導致應用程序延遲,那么您可能必須找到一種更好的方法來解決此問題,使用直接引用您的函數,而不是通過委托。

  1. 當他們可以過度殺戮

當你無償地使用它們而沒有任何實際需要時。 否則,在大多數情況下,它們可以是解決上述場景的優雅方式。

另外,請閱讀此SO答案以了解正常方法之間的區別,委托以更好地了解使用委托/ action / func的位置https://stackoverflow.com/a/17380580/1336068

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM