2011-11-17 80 views
1

我有一個類的方法將傳遞一個字符串。該方法將對該字符串執行一些操作,然後將該字符串傳遞給某個可以對該字符串執行其他操作的對象。委託或反思?

因此,它基本上是這樣的:

class Main 
{ 
    public Main() 
    { 
     strClass str = new strClass(this); 
    } 

    public function handler () 
    { 
     console.log("No string is passed yet, but this method is called from receiveData()"); 
    } 
} 

class strClass 
{ 
    object handler; 
    public strClass (handler) 
    { 
     // save the object 
     this.handler = handler; 
    } 

    public receiveData (string str) 
    { 
     // This method does some stuff with the string 
     // And it then passes it on to the supplied object (handler) which will do 
     // the rest of the processing 

     // I'm calling the "handler" method in the object which got passed in the 
     // constructor 
     Type thisType = this.handler.GetType(); 
     MethodInfo theMethod = thisType.GetMethod("handler"); 
     theMethod.Invoke(this.handler, null); 
    } 
} 

現在這個代碼的工作好,用反射的東西。但我想知道,這不應該是可能的(甚至更好?)與代表?如果是這樣,我怎麼可以通過使用委託實現這一點呢?

+3

編譯器錯誤,使它一點點努力,以確保我們在這裏回答同樣的問題.. 。它會很好,如果它運行(因爲它「運作良好」) –

回答

4

委託是一個更好的選擇。

class Main 
{ 

    public Main() 
    { 
     StrClass str = new StrClass(this.Handler); 
    } 

    public void Handler () 
    { 
     //called from recieve data 
    } 
} 

class StrClass 
{ 
    readonly Action _handler; 
    public StrClass (Action callback) 
    { 
     // save the object 
     this._handler = callback; 
    } 

    public void receiveData(string str) 
    { 
     this._handler(); 
    } 
} 
+0

謝謝,這工作很好,似乎是一個更好的解決方案,然後我有什麼。 – w00

5

你不能使用接口來代替:

interface IStringHandler { 
    void HandleString(string s); 
} 


class strClass 
{ 
     IStringHandler handler = null; 

     public strClass(IStringHandler handler) 
     { 
      this.handler = handler; 
     } 

     public void ReceiveData(string s) 
     { 
      handler.HandleString(s); 
     } 
} 


class Main : IStringHandler 
{ 
     // Your code 
} 
0

首先,如果你必須按名稱調用一個未知的方法,使用dynamic - 這在很大程度上爲這種優化的(雖然仍然不是一個好主意):

((dynamic)handler).handler(); // but please don't use this! see below 

但是,我反而看或者是Action<string>(或者可能是Func<string,string>),或者是其上具有已知方法的接口。

2

您可以用Action這樣做:

class Main 
{ 
    public Main()  
    { 
     strClass str = new strClass(newString => 
     { 
      console.log("This string I got back: " + newString);  
     }); 
    } 
} 
class strClass 
{  
    Action<string> callback; 
    public strClass (Action<string> callback) 
    { 
     // save the action 
     this.callback = callback;  
    } 
    public receiveData (string str)  
    { 
     // Do something with the string 
     callback(str); 
    } 
} 
0

基本上,你想改變你如何對象StrClass反應,開始接收數據。聽起來像事件給我。

這樣的事情,那就是你有兩個在Main,並且在一般HandlerObject處理方法:

class StrClass : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged = null; 
    public void OnPropertyChanged(object sender, PropertyChangedEventArgs e) 
    { 
     if (PropertyChanged != null) 
      PropertyChanged(this, e); 
    } 

    private string receivedString; 
    public string ReceivedString 
    { 
     get; 
     set 
     { 
      string oldStr = receivedString; 
      receivedString = value; 
      PropertyChanged(receivedString, new PropertyChangedEventArgs("ReceivedString")); 
     } 
    } 

    public void receiveData(string str) 
    { 
     //event fires here 
     ReceivedString = str; 
    } 
} 

class HandlerObject 
{ 
    public void HandlerMethod1(string s) 
    { 
     //magic 
    } 

    public void HandlerMethod2(string s) 
    { 
     //different kind of magic 
    } 
} 

class Program 
{ 
    static void HandlerMethod3(string s) 
    { 
     //another kind of magic! 
    } 

    static void Main(string[] args) 
    { 
     StrClass class1 = new StrClass(); 
     StrClass class2 = new StrClass(); 
     StrClass class3 = new StrClass(); 

     HandlerObject handler = new HandlerObject(); 

     class1.PropertyChanged += (s, e) => { handler.HandlerMethod1(s.ToString()); }; 
     class2.PropertyChanged += (s, e) => { handler.HandlerMethod2(s.ToString()); }; 
     class3.PropertyChanged += (s, e) => { HandlerMethod3(s.ToString()); }; 
    } 
}