![](/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.