关于c#:将接口转换为其具体实现对象,反之亦然?

Cast interface to its concrete implementation object or vice versa?

在C中,当我有一个接口和多个具体实现时,我可以将接口强制转换为具体类型还是具体类型强制转换为接口?

在这种情况下,规则是什么?


两个方向都允许在爪哇和C。向下转换需要显式转换,如果对象类型不正确,则可能引发异常。然而,向上转换不需要显式转换,而且总是安全的。

也就是说,假设您有public interface Animal和这个interfaceCatDog的两个实现……

1
2
3
4
5
6
7
Animal meowAnimal = new Cat();  // No cast required
Animal barkAnimal = new Dog();  // No cast required

Cat myCat = (Cat) meowAnimal; // Explicit cast needed
Dog myDog = (Dog) barkAnimal; // Explicit cast needed

Dog myPet = (Dog) meowAnimal; // Will compile but throws an Exception

你需要一个围绕显式类型转换的try/catch。在C中,您有有用的as关键字:

1
2
Dog myDog = barkAnimal as Dog;
Dog myPet = meowAnimal as Dog;

不会抛出异常,mydog将不为空,mypet将为空。Java没有等效的关键字,尽管您可以始终使用EDCOX1和8个测试来保持类型安全。(我猜"as关键字生成的字节码执行if操作,指定is的空值失败)。但是.NET可能有一个字节码指令,它的作用相当于"as"。


在大多数语言中,你可以双向投射。如果您有一个具体的类,您可以将它强制转换到接口。如果您有一个接口,则可以将其强制转换为具体类。

一般来说,你只想朝第一个方向走。原因是当您只有一个指向接口的指针时,您不应该知道具体类是什么。如果您将某个东西作为一个接口传递,那么您应该能够从该接口做您需要做的任何事情。如果您发现自己需要使用不在界面上的具体对象的某些部分,那么您就有了一个设计问题,该问题应该被修复,而不是强制转换。


如果你说的是Java(但是其他语言的规则是相似的),它就是这样:

您可以(向下)将接口强制转换为具体的实现,如果您强制转换的引用实际上是对具体实现的引用。那意味着

1
2
3
Vehicle v=new Car();
(Car)v // this is OK
(Bus)v // this is not

该错误在Java中表现为EDCOX1×0Ω。

您可以自由地将接口的具体实现上推到接口上。


一个接口可以是整个类,但是如果不必是,那么最好创建一个接受接口作为参数并复制设置的构造函数,这样您就可以控制发生了什么以及需要什么。


两者都是有效的,因为这是一个逻辑类型。很多时候,您的接口使用者无法访问具体的类,这是首先拥有接口的一个主要原因。