2014-02-15 26 views
1

C#中是否有可能在基類的不同後代中使用不同簽名重載方法,然後根據重載方法的參數的運行時類型調用適當的方法?運行時方法重載不同的類

作爲背景,我正在研究消息處理過程,從編譯時不知道消息類型的點開始,以及隨着時間的推移不同類型的消息處理功能。理想情況下,新的消息處理會改變子類而不是基類。通過在基類中包含所有類型化的方法並基於消息類型顯式選擇正確的方法,它現在可以正常工作。這個問題主要是由好奇心驅動的,因爲基於對this question的回答,我期望它應該是可能的。如果我過於複雜並且更簡單,我也會歡迎這種建議。表示本

實施例的代碼是下面,我預期HandleTypedMessage(BaseMessage MSG)HandleTypedMessage(MessageA MSG)到被調用一次每個,代替HandleTypedMessage(BaseMessage MSG)被調用兩次。

class Program 
{ 
    static void Main(string[] args) 
    { 
     var msga = new MessageA(); 
     var msgb = new MessageB(); 
     MessageHandler handlerA = new MessageHandlerA(); 

     handlerA.HandleTypedMessage((dynamic) msga); 

     handlerA.HandleTypedMessage((dynamic) msgb); 

     Console.ReadLine(); 
    } 
} 

public interface IHandlesMessage 
{ 
    void HandleMessage(BaseMessage message); 
} 

public abstract class BaseMessage 
{ 
    public abstract string MessageType { get; } 
} 

public class MessageA : BaseMessage 
{ 
    public override string MessageType 
    { 
     get { return "http://message/a"; } 
    } 
} 

public class MessageB : BaseMessage 
{ 
    public override string MessageType 
    { 
     get { return "http://message/a"; } 
    } 
} 

public abstract class MessageHandler 
{ 
    public abstract void HandleTypedMessage(BaseMessage msg); 
} 

public class MessageHandlerA : MessageHandler 
{ 
    public override void HandleTypedMessage(BaseMessage msg) 
    { 
     Console.WriteLine("Did nothing with " + msg.MessageType); 
    } 

    public void HandleTypedMessage(MessageA msg) 
    { 
     Console.WriteLine("Handled message a"); 
    } 

} 

public class MessageHandlerB : MessageHandler 
{ 
    public override void HandleTypedMessage(BaseMessage msg) 
    { 
     throw new NotImplementedException(); 
    } 

    public void HandleTypedMessage(MessageB msg) 
    { 
     System.Console.WriteLine("Handled message b"); 
    } 
} 

回答

2

您正在使方法調用dynamic的部分不正確。使目標dynamic,不是參數:

((dynamic)handlerA).HandleTypedMessage(msga); 
((dynamic)handlerA).HandleTypedMessage(msgb); 

它會尋找最佳匹配HandleTypedMessage方法實際類型handlerA點(MessageHandlerA),而不是它的聲明(MessageHandler)之一。

以上代碼打印

Handled message a 
Did nothing with http://message/a 
+0

完美。剛注意到我在兩個消息類中都留下了相同的MessageType屬性,但是很清楚發生了什麼 – Rattle

1

一種方法是將dynamic派遣進入處理程序sublcasses這樣的:

public class MessageHandlerA : MessageHandler { 
    public override void HandleTypedMessage(BaseMessage msg) { 
     this.HandleTypedMessageCore((dynamic) msg); 
    } 

    private void HandleTypedMessageCore(BaseMessage msg) { 
     Console.WriteLine("Did nothing with " + msg.MessageType); 
    } 

    private void HandleTypedMessageCore(MessageA msg) { 
     Console.WriteLine("Handled message a"); 
    } 
} 
+0

謝謝 - 這可行,但我接受了Marcin的答案,因爲更改更簡單。 – Rattle

相關問題