2010-09-17 46 views
2

我理解代表作爲使用一種方法定義類的快捷方式,但以下bar2的含義是什麼?它編譯。但我看不出內部班會在這裏做什麼。我知道我錯過了一些東西,這就是爲什麼我要問(這不是家庭作業,我現在正在工作)。一個代表在課堂內的含義是什麼?

namespace ns2 { public delegate void bar();} 
public class foo 
{ 
    private ns2.bar _callback; 
    public foo(ns2.bar callback) { _callback = callback; } 
    public void baz() { _callback(); } 
    public delegate void bar2(); 
} 

謝謝!

回答

6

這只是聲明一個嵌套類型,就這些。由於它是公開的,在類型中聲明和在外部聲明之間幾乎沒有區別。

其他類人員都將通過包含類型的名稱來指代它(除非他們有一個using指令專門爲它):

public class OtherClass 
{ 
    private void DoSomething() 
    { 
     foo.bar2 action = delegate { ... }; 
     foo f = new foo(action); 
     ... 
    } 
} 

通常當我寫一個嵌套的類型,它是私有的 - 它只是包含類的助手類;一個實現細節。當然,情況並非如此,但至少應該是這樣的,即嵌套類型是毫無意義的,除非您使用外部類的方式使用的某些。例如,它可以是外部類的構建器,也可以是外部類中的方法調用的某些參數中使用的枚舉。

(順便說一下,它編寫的代碼示例這樣當遵循.NET命名約定,即使對於像FooBar元語法名稱是非常有用的,它使變量和類型更清晰的區別,例如。)

+0

感謝您的答案和提示。 – 2010-09-17 16:54:31

7

委託並不是用一種方法定義類的快捷方式。它們實際上至少有6種方法(Invoke,BeginInvoke,EndInvoke,GetHashCode,Equals,ToString)。

將代表放入某個類型的模式的一個原因是爲了避免全局命名空間污染。代表bar2只能通過foo的合格參考進行訪問。如果bar2是一個具有多個有效含義的名稱並且將其放入foo以提供必要的上下文,則這可能很有用。

+0

+1,不喜歡使用一種方法定義類的快捷方式。必須是來自Java的匿名類的遺留。 – 2010-09-17 16:41:49

+2

將一個委託類型想象成一個*接口*,使用一個方法IMO,然後再爲異步操作調用該方法更爲合理。對我來說,代表正確的*感覺*。出於興趣,保證'BeginInvoke',但'EndInvoke'不保證? – 2010-09-17 16:43:44

+0

@Jon,'EndInvoke'也有保證(更新我的答案)。 – JaredPar 2010-09-17 16:47:20

8

要添加到Jon和Jared的答案中,我注意到,通常在類中定義委託的唯一時間是委託是類的私有實現細節。在一個類中有一個public委託定義是罕見的和奇怪的。

例如,考慮我喜歡的圖案:一個抽象基類,只能通過與工廠生產的私人嵌套類擴展:

public abstract class Animal 
{ 
    private Animal() { } // prevents subclassing from outside! 
    private sealed class Giraffe : Animal { } 
    private sealed class Leopard : Animal { } 
    public static Animal GetGiraffe() { return new Giraffe(); } 
    public static Animal GetLeopard() { return new Leopard(); } 

假設動物的實現細節是,你需要有從長頸鹿到豹的代表:

private delegate Leopard D(Giraffe g); 

這不能是公共委託類,因爲它指的是私有類型!

現在當然你甚至不會這樣做。你會使用Func<Giraffe, Leopard>,你就完成了。

因此,嵌套的委託類型幾乎是爲了完整性和向後兼容性;通常你不會使用它。