![](/img/trans.png)
[英]Can I cast from an interface to a concrete type with another interface implementation
[英]Why can I not type cast Interface into its concrete implementation?
這是一個非常瑣碎的問題,由於我缺乏經驗,這似乎很煩人,但是為什么我不能做這樣的事情:
public interface INetworkMessage { ... }
public class NetworkDataMessage : INetworkMessage { ... }
public void ParseMessage (INetworkMessage message)
{
Type concreteMessageType = message.GetType();
var concreteMessageInstance = message as concreteMessageType;
...
// Now in theory I could work with a concrete type?
}
要回答您的問題:您可以使用強制轉換操作和編譯時類型名稱直接強制轉換對象:
var concreteMessageInstance = (NetworkDataMessage)message; //may throw InvalidCastException for different implementation of INetworkMessage
要么
var concreteMessageInstance = message as NetworkDataMessage;
if(concreteMessageInstance != null) { /* ... */ }
但是:如果需要通過接口進行具體實現,則應該重新考慮設計。 界面的整個想法是細節無關緊要-也許您要在具體類型上嘗試做的事情應該移到界面中? 或者,也許您應該直接使用具體類型而不是在界面上跳過? 兩者都是您應該考慮的設計決策。
如果您希望能夠動態地轉換為接口的任何具體實現並調用某些操作,則必須將操作從具體類型移至接口。 強制轉換只會增加額外的開銷,並且設計良好的應用程序從一開始就將在接口定義中進行此類操作。
您只能使用as
強制轉換為在編譯時指定的類型(直接或通過泛型)。 您的代碼將無法編譯。
由於您在編譯時不知道什么是concreteMessageType
,因此也無法使用concreteMessageInstance
(如果可能的話,因為方法/屬性/字段/等)。 您將使用編譯器需要知道的信息。
我最終以自己的方式聽從了大衛的建議:
public void ParseMessage<T> (INetworkMessage message) where T : INetworkMessage
{
// So now I can do
var concreteInstance = (T)message;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.