2010-01-11 89 views
123

我很困惑,代表的實際角色是什麼?在我的採訪中,我多次被問過這個問題,但我不認爲面試官對我的答案感到滿意。什麼是代表?

任何人都可以用一個實際的例子用一句話告訴我最好的定義嗎?

感謝

+18

出於好奇,你有什麼反應,所以我們可以告訴你如何糾正它? – 2010-01-11 19:28:34

回答

140

我喜歡把委託的爲「指向函數的指針」。這回到C日,但這個想法仍然成立。

這個想法是,你需要能夠調用一段代碼,但你要調用的那段代碼直到運行時才知道。所以你使用「委託」來達到這個目的。例如,代表們可以很方便地處理事件處理程序等事情,例如,根據不同的事件執行不同的事情。

Here's爲C#的參考,你可以看看:

在C#中,例如,假設我們有我們想要做一個計算,我們想用不同的計算方法,我們不知道,直到運行。因此,我們可能有一對夫婦的計算方法是這樣的:

public static double CalcTotalMethod1(double amt) 
{ 
    return amt * .014; 
} 

public static double CalcTotalMethod2(double amt) 
{ 
    return amt * .056 + 42.43; 
} 

我們可以宣佈一個委託簽名是這樣的:

public delegate double calcTotalDelegate(double amt); 

然後,我們可以宣佈它接受委託作爲這樣的參數的方法:

public static double CalcMyTotal(double amt, calcTotalDelegate calcTotal) 
{ 
    return calcTotal(amt); 
} 

而且我們可以調用CalcMyTotal方法傳遞我們想用委託方法。

double tot1 = CalcMyTotal(100.34, CalcTotalMethod1); 
double tot2 = CalcMyTotal(100.34, CalcTotalMethod2); 
Console.WriteLine(tot1); 
Console.WriteLine(tot2); 
+17

+1點的簡單但有效的功能指針在C點。 – 2010-01-11 19:28:42

+3

一個問題與你的答案有關。與以正常方式調用函數有什麼不同?僅僅因爲它在運行時不知道? – NAVEED 2010-01-11 19:51:06

+0

@NAVEED - 參考我最近的編輯,我列舉了一個例子。就實際的方法調用而言,它和上面例子中的正常方法調用沒有任何區別(calcTotal(amt)調用委託),但委託的強大之處在於您可以將它們用作參數,等等,當你想要一個方法能夠有不同的行爲。還有很多其他的東西可以用於他們,這只是一個簡單的例子。希望有所幫助。 – dcp 2010-01-11 20:10:14

16

委託只是一個函數指針。
只需指定您希望運行委託的方法。 然後在代碼中,您可以通過Invoke調用該方法。

一些代碼來演示(寫這從存儲器這樣的語法可以是關閉)

delegate void delMyDelegate(object o); 

private void MethodToExecute1(object o) 
{ 
    // do something with object 
} 

private void MethodToExecute2(object o) 
{ 
    // do something else with object 
} 

private void DoSomethingToList(delMyDelegate methodToRun) 
{ 
    foreach(object o in myList) 
     methodToRun.Invoke(o); 
} 

public void ApplyMethodsToList() 
{ 
    DoSomethingToList(MethodToExecute1); 
    DoSomethingToList(MethodToExecute2); 
} 
4

想一想委託作爲關於簡化實現Command模式。

13

Taken from here

Q什麼是代表?
A當一個對象接收到一個請求時,該對象可以自己處理該請求,或者將該請求傳遞給另一個對象來完成該工作。如果對象決定傳遞請求,則表示該對象已將處理請求的責任轉發給第二個對象。

或者,作爲一個簡單的僞示例:某事發送請求到object1。 object1然後將請求和自身轉發給object2 - 委託。 object2處理請求並做一些工作。(注:以上鍊接提供了很好的例子)

+0

上面的鏈接中給出的示例沒有正確指出委派。 – 2017-06-14 11:55:04

-1

雖然不是一個真正的「函數指針」,一個代表可能看起來像這是一個動態語言如PHP:

 


$func = 'foo'; 
$func(); 

function foo() { 
    print 'foo'; 
} 
 

或在JavaScript中,你可以做類似:

 

var func = function(){ alert('foo!'); } 
func(); 
 
+2

這不是委派的例子。在你的例子中,你正在使用所謂的變量函數,它基本上尋找一個與變量引用的字符串具有相同名稱的函數。 查看變量函數:http://php.net/manual/en/functions.variable-functions.php – Aquarelle 2013-08-27 04:46:23

1

很好的解釋和委託模式的實際執行可以在谷歌集合Forwarding類(也,Decorator模式)中找到。

1

在事件通信發件人不知道哪個對象將處理事件。 代表是持有方法的參考的類型。 代表具有簽名並持有與其簽名 匹配的方法的引用,因此Delegate與類型安全函數指針類似。

button1.Click + =新System.EventHandler(的button1_Click) System.EventHandler聲明爲代表這裏 在.NET活動上代表的概念工作(如按鈕單擊)

委託時使用你不知道在運行時 調用所以當時代表用於處理事件

http://msdn.microsoft.com/en-us/library/ms173171(v=vs.80).aspx

0

委託其代碼是其中一個題目被委託的東西。授權的主要目的是分離代碼並提供更大的靈活性和重用性。

在編程,特別是面向對象編程中,這意味着當一個方法被調用來完成一些工作時,它將工作傳遞給它所引用的另一個對象的方法。只要對象符合預定義的一組方法,引用就可以指向我們希望的任何對象。我們稱之爲「編程接口」(與具體類實現編程相對)。一個接口基本上是一個通用模板,沒有實現;它只是一個配方,一套方法,前置條件和後置條件(規則)。

簡單的例子:

SomeInterface 
{ 
    public void doSomething(); 
} 


SomeImplementation implements SomeInterface 
{ 
    public void doSomething() 
    { 
     System.err.println("Was it good for you?"); 
    } 

} 


SomeCaller 
{ 
    public void doIt(SomeInterface someInterface) 
    { 
     someInterface.doSomething(); 
    } 
} 

現在你看到了,我可以在任何時候使用我想要的實現,而不在SomeCaller改變代碼,因爲doIt()傳遞的類型不是混凝土,而是抽象的,因爲它是一個接口。在Java世界中,這通常表示在服務範例中,您向服務發出呼叫(一個對象通過特定接口將其本身稱爲服務),然後該服務會呼叫代表以幫助其完成工作。該服務的方法被命名爲粗粒度任務(makePayment(),createNewUser()等),而在內部它通過委託來完成大量工作,而委託的類型是接口而不是具體實現。

SomeService 
{ 
    SomeInterface someImplementation = ... // assign here 
    SomeOtherInterface someOtherImplementation = ... // okay, let's add a second 

    public void doSomeWork() 
    { 
     someImplementation.doSomething(); 
     someOtherImplementation.doSomethingElse(); 
    } 
} 

(N.B .:如何被分配的實現超出了本線程。控制和依賴注入的查找反轉的範圍。)

2

委託是一個對象,它可以參考的方法。因此,當我們創建一個委託時,我們正在創建一個可以保存對方法的引用的對象。此外,該方法可以通過該引用來調用。因此,委託可以調用它引用的方法。 委託的主要優點是它允許我們指定對方法的調用,但實際調用的方法是在運行時確定的,而不是在編譯時確定的。

簡單的委託

Declaration of delegate: 
delegate-modifier delegate return-type delegate-name(parameters) 
Implementation of delegate: 
Delegate-name delegate-object=new Delegate-name(method of class) 

http://knowpacific.wordpress.com/2012/01/26/delegate/

2

在這裏,我要解釋的代表,多播代表及其用法.. 代表是保持在一個方法(或多個)基準的類型目的。它也被稱爲類型安全函數指針。我們可以說委託是一種定義方法簽名的類型。

當您實例化一個委託時,可以將其實例與具有兼容簽名的任何方法相關聯。您可以通過委託實例調用(或調用)該方法。 委託用於將方法作爲參數傳遞給其他方法。 事件處理程序只不過是通過委託來調用的方法。 使用委託的好處是, 封裝來自調用者的方法調用 委託的有效使用提高了應用程序的性能 用於異步調用方法。 有代表的某些屬性

Delegates are like C++ function pointers but are type safe. 
Delegates allow methods to be passed as parameters. 
Delegates can be used to define callback methods. 
Delegates can be chained together; for example, multiple methods can be called on a single event. 
Methods do not have to match the delegate signature exactly. 

公共委託type_of_delegate delegate_name()//聲明

You can use delegates without parameters or with parameter list 
If you are referring to the method with some data type then the delegate which you are declaring should be in the same format. This is why it is referred to as type safe function pointer. Here I am giving an example with String. 

下面的示例顯示了一個委託操作:

namespace MyDelegate 
    { 
     class Program 
     { 
      private delegate void Show(string s); 


      // Create a method for a delegate. 
      public static void MyDelegateMethod(string me 

ssage) 
     { 
      System.Console.WriteLine(message); 
     } 

     static void Main(string[] args) 
     { 
      Show p = MyDelegateMethod; 
      p("My Delegate"); 
      p.Invoke("My Delegate"); 
      System.Console.ReadLine(); 
     } 
    } 
} 

什麼是組播代表?

這是一個委託,它擁有多種方法的參考。多播委託必須只包含返回void的方法,否則存在運行時異常。

delegate void MyMulticastDelegate(int i, string s); 
Class Class2 
{ 
    static void MyFirstDelegateMethod(int i, string s) 
    { 
    Console.WriteLine("My First Method"); 
    } 

    static void MySecondDelegateMethod(int i, string s) 
    { 
    Console.WriteLine("My Second Method"); 
    } 

    static void Main(string[] args) 
    { 
    MyMulticastDelegate Method= new MyMulticastDelegate(MyFirstDelegateMethod); 
    Method+= new MyMulticastDelegate (MySecondDelegateMethod); 
    Method(1,"Hi");    // Calling 2 Methodscalled 
    Method-= new MyMulticastDelegate (MyFirstDelegateMethod); 
    Method(2,"Hi");    //Only 2nd Method calling 
    } 
} 

這裏委託使用+ =運算符添加並使用 - =運算符刪除。

委託類型派生自.NET Framework中的委託類。代表類型是密封的 - 它們不能派生。 因爲實例化的委託是一個對象,所以它可以作爲參數傳遞,或者分配給一個屬性。這允許一個方法接受委託作爲參數,稍後再調用委託。這被稱爲異步回調。

0

代表主要用於事件。

我們需要的是:

你不想的時候,當你運行該程序執行一段代碼。 運行程序後,您希望在事件發生時執行該代碼段。

例子:

  1. 控制檯應用程序 - 代碼只能在運行該程序時執行。 (書面Main方法內側)
  2. Windows應用程序(用戶界面編程) - 代碼可以運行該程序後點擊該按鈕時執行。

這就是他們說的,你不知道哪個方法會在編譯時調用。只有在運行時才知道它是在單擊按鈕時。

沒有代表沒有用戶界面編程是可能的。因爲你正在執行每當用戶使被點擊按鈕,在文本框中鍵入事件,選擇下拉列表項等代碼....

1

一個委託對象 是一個對象,當事情發生在另一個對象諮詢那個對象。對於 實例,如果您的汽車出現問題,您的維修人員就是您的代表。你去找你的修理工,並要求他爲你修理汽車(儘管有些人更喜歡自己修理汽車,在這種情況下,他們是他們自己的汽車的代表)。

1

委託是表示指向函數的指針的對象。然而,這不是因爲它的普通函數指針:

1)是面向對象的

2)是類型安全的,即它只能指向一個方法,你不能讀取原始內存地址是指向

3)強類型。它只能指向匹配其簽名的方法。

4)可以同時指向多個方法。