繁体   English   中英

为什么不能将强制转换接口键入其具体实现?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM