为什么我不能在其具体实现中键入castInterface
本文关键字:实现 castInterface 不能 为什么 | 更新日期: 2023-09-27 18:24:06
这里有一个非常琐碎的问题,由于我缺乏经验,这个问题看起来很烦人,但是,为什么我不能做这样的事情:
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
(如果可以进行这种强制转换的话),因为方法/properties/fiields等。您将使用需要被编译器知道。
我最终以自己的方式遵循了David的建议:
public void ParseMessage<T> (INetworkMessage message) where T : INetworkMessage
{
// So now I can do
var concreteInstance = (T)message;
}