2016-02-05 20 views
0

我是C#的新手,仍然理解代表的概念。我對代表的瞭解是代表們定義了一個函數簽名,並且可以將具有相同簽名的函數添加到該代理中。使用代表在運行時選擇函數

public class ss 
{ 
    public delegate void sampleDelegate(); 

    public ss() 
    { 
     sampleDelegate s1 = new sampleDelegate(sampleMethod); 
     s1+= new sampleDelegate(sampleMethod2); 
     s1(); 
    } 


    public static void sampleMethod() 
    { 

    } 
    public static void sampleMethod2() 
    { 

    } 
} 

在上面的代碼中,我創建了一個委託併爲其提供sampleMethod和sampleMethod2。當我調用s1()時,它調用sampleMethod()和sampleMethod2()。

如果我只想調用其中一種方法,並且決定在運行時作出,該怎麼辦?

我可能會錯過一些非常小的東西,但代表真的很難理解。

回答

0

委託人就像指向方法的指針。在運行時,有沒有什麼區別調用委託或排除的方法是對象的成員方法:

some.Method(); 
someDelegate(); 

代表的目標是創建一個黑箱你想到哪裏一些代碼來放一些行爲,而你只是依靠方法簽名。

在一天結束的時候,他們就像方法接口

// It must be a parameterless method which returns no value 
public delegate void Action(); 

// vs 

// It must be a class which implements a parameterless method "Do" 
// which returns no value 
public interface Action 
{ 
    void Do(); 
} 

也就是說,一個方法不能有條件地與其他切換,但你需要使用常規的控制流像ifswitch這樣的塊來做出關於做什麼的決定

爲了不重複喬恩斯基特的答案,我會添加其他可能的解決方案:而不是創建的sampleDelegate兩個實例

string text = ""; 

    sampleDelegate s1 =() => 
    { 
     if(!string.IsNullOrEmpty(text)) 
     { 
      SampleMethod1(); 
     } 
     else 
     { 
      SampleMethod2(); 
     } 
    }; 

    s1(); 

檢查,您可以創建一個處理條件邏輯致電SampleMethod1SampleMethod2

整個() => { }東西叫做匿名代理

它也可以表述如下:

string text = ""; 

    sampleDelegate s1 = delegate() 
    { 
     if(!string.IsNullOrEmpty(text)) 
     { 
      SampleMethod1(); 
     } 
     else 
     { 
      SampleMethod2(); 
     } 
    }; 

但上面的語法不使用......它來自舊.NET天(.NET 1.0/1.1/2.0)。

總之,委託人可以或不可以作爲實際的類方法提供,但您可以將類方法與匿名委託組合起來以滿足您的需求

如果我只想調用其中一種方法,並且決定在運行時創建 會怎麼樣?我可能會錯過一些非常小的東西,但代表們真的很困惑,不能理解。

其實這是使用委託的原因,但你說得對,當你說你失去了一些東西。

代表用來情況類似下面的一個:

public void DoStuff(string text, Func<string, string> textFormatter = null) 
{ 
    Console.WriteLine(textFormatter != null ? textFormatter(text) : text); 
} 

你可以稱呼DoStuff要麼這樣DoStuff("hello world")DoStuff("hello world", text => $"<strong>{text}</strong>")

DoStuff方法實現不知道如何格式化給定的文本,並且您提供了一個可選參數以將委託作爲參數來接收要格式化的整個文本,並且它將返回格式化文本。

這是不是有點有條件畢竟?根據調用者,DoStuff以自定義的方式格式化文本。你甚至可以提供一個默認的格式:

public void DoStuff(string text, Func<string, string> textFormatter = null) 
{ 
    // We'll give a default formatter if none is provided ;) 
    if(textFormatter == null) 
     textFormatter = text => $"<span>{text}</span>"; 

    Console.WriteLine(textFormatter(text)); 
} 
2

如果我只想調用其中一種方法,並且決定在運行時作出,該怎麼辦?

那麼你不要把它們結合在一起,基本上。例如:

// Names changed to be more conventional 

SampleDelegate s1 = someCondition 
    ? new SampleDelegate(SampleMethod) 
    : new SampleDelegate(SampleMethod2); 
// This will call either SampleMethod or SampleMethod2, depending on condition 
s1(); 

需要注意的是,通常我會使用一個方法組轉換,但你不能使用方法組的條件運算符的第二個和第三個操作數。你可以使用:

SampleDelegate s1; 
if (condition) { 
    s1 = SampleMethod; 
} else { 
    s2 = SampleMethod2; 
} 

...或

SampleDelegate s1 = someCondition 
    ? new SampleDelegate(SampleMethod) 
    : SampleMethod2; 

無論這些看起來特別對我很好,雖然。

+0

所以你說的是這是不可能使用委託沒有if/else語句或開關的情況下進行選擇來運行特定的方法是什麼? – AnoopDV

+0

@AnoopDV:我不確定你在問什麼。你必須使用條件*某處*,是的...你還希望在多個選項之間進行選擇?這種情況可以用多種方式表達出來...... –