[英]What is the difference between Delegate & Action in C#
如果我搜索過,我肯定會得到一個顯示什么是委托和行動的例子。 我已經閱讀了基本書籍,給出了代表的例子。
但我想知道的是它們在現實世界中的應用。 請不要給Hello World示例或動物類它們太基本了
例如:
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委托的情況也是如此。
真的更方便,而不是實際的新功能。 幫助您保持代碼簡短易懂,減少麻煩。
至於你的觀點問題,
沒有不同。 Action是一個預定義的委托,旨在為您省去重復定義新委托的麻煩。
通常,委托(和操作)用於需要具有表驅動功能的位置。 即,可能是對應於某些特定要求的方法的字典。 請注意,在此處使用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
我認為在情況需要時不使用它們的唯一原因是,如果你的代表將在短時間內被召喚數百萬次。 涉及到一些輕微的開銷,如果這導致應用程序延遲,那么您可能必須找到一種更好的方法來解決此問題,使用直接引用您的函數,而不是通過委托。
當你無償地使用它們而沒有任何實際需要時。 否則,在大多數情況下,它們可以是解決上述場景的優雅方式。
另外,請閱讀此SO答案以了解正常方法之間的區別,委托以更好地了解使用委托/ action / func的位置https://stackoverflow.com/a/17380580/1336068
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.