简体   繁体   English

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

[英]Why can I not type cast Interface into its concrete implementation?

Here is a very trivial problem that seems rather annoying due to my lack of experience but, why can I not do something like this: 这是一个非常琐碎的问题,由于我缺乏经验,这似乎很烦人,但是为什么我不能做这样的事情:

 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?
 }

To answer your question: you can directly cast the object using a cast operation and the compile-time type name: 要回答您的问题:您可以使用强制转换操作和编译时类型名称直接强制转换对象:

var concreteMessageInstance = (NetworkDataMessage)message; //may throw InvalidCastException for different implementation of INetworkMessage

Or 要么

var concreteMessageInstance = message as NetworkDataMessage;
if(concreteMessageInstance != null) { /* ... */ }

However: you should rethink your design if you need a concrete implementation from an interface. 但是:如果需要通过接口进行具体实现,则应该重新考虑设计。 The whole idea of the interface is that the details don't matter - maybe the thing you're trying to do on the concrete type should be moved into the interface? 界面的整个想法是细节无关紧要-也许您要在具体类型上尝试做的事情应该移到界面中? Or maybe you should use the concrete type directly instead and skip out on the interface? 或者,也许您应该直接使用具体类型而不是在界面上跳过? Both are design decisions you should consider. 两者都是您应该考虑的设计决策。

If you want to be able to cast to any concrete implementation of the interface dynamically and invoke some operation, then you DEFINITELY should move the operation from the concrete type to the interface. 如果您希望能够动态地转换为接口的任何具体实现并调用某些操作,则必须将操作从具体类型移至接口。 The cast just adds extra overhead and a well-designed application would have such an operation in the interface definition from the start. 强制转换只会增加额外的开销,并且设计良好的应用程序从一开始就将在接口定义中进行此类操作。

You can only use as to cast to a type which you specify at compile time (either directly or via generics). 您只能使用as强制转换为在编译时指定的类型(直接或通过泛型)。 Your code won't compile. 您的代码将无法编译。

Since you don't know at compile time what concreteMessageType is, you also can't use concreteMessageInstance (if such a cast were possible), since the methods/properties/fields/etc. 由于您在编译时不知道什么是concreteMessageType ,因此也无法使用concreteMessageInstance (如果可能的话,因为方法/属性/字段/等)。 you would use need to be known by the compiler. 您将使用编译器需要知道的信息。

I ended up following David's suggestion in my own way: 我最终以自己的方式听从了大卫的建议:

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