C# 将接口转换为它的具体实现对象,反之亦然?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/539436/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Cast interface to its concrete implementation object or vice versa?
提问by GurdeepS
In C#, when I have an interface and several concrete implementations, can I cast the interface to a concrete type or is concrete type cast to interface?
在 C# 中,当我有一个接口和几个具体实现时,我可以将接口转换为具体类型还是将具体类型转换为接口?
What are the rules in this case?
这种情况下的规则是什么?
采纳答案by Eddie
Both directions are allowed in Java and C#. Downcasting needs an explicit cast and may throw an Exception if the object is not of the correct type. Upcasting, however, needs no explicit cast and is always safe to do.
Java 和 C# 中允许两个方向。向下转换需要显式转换,如果对象的类型不正确,则可能会抛出异常。然而,向上转换不需要显式转换并且总是安全的。
That is, assuming you have public interface Animal
and two implementations of this interface
, Cat
and Dog
....
也就是说,假设你有public interface Animal
和这两个实现interface
,Cat
并且Dog
....
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
and you'll want a try
/ catch
around the explicit casts. In C# you have the useful as
keyword:
你会想要一个try
/catch
围绕显式转换。在 C# 中,你有一个有用的as
关键字:
Dog myDog = barkAnimal as Dog;
Dog myPet = meowAnimal as Dog;
No exception will be thrown, and myDog will be nonNull and myPet will be null. Java does not have an equivalent keyword although you can always use if (meowAnimal instanceof Dog)
tests to keep type safety. (I would guess that the "as
" keyword generates bytecode that does the if, assigning null of the is
fails. But perhaps .NET has a bytecode instruction that does the equivalent of "as
".)
不会抛出任何异常,并且 myDog 将为 nonNull 并且 myPet 将为 null。Java 没有等效的关键字,尽管您始终可以使用if (meowAnimal instanceof Dog)
测试来保持类型安全。(我猜想“ as
”关键字会生成执行 if 的字节码,分配is
失败的空值。但也许 .NET 有一个字节码指令,相当于“ as
”。)
回答by BC.
Both are valid, considering it's a logical cast. Many times, your interface consumers don't have access to the concrete classes which is one major reason to have an interface in the first place.
考虑到这是一个合乎逻辑的演员,两者都是有效的。很多时候,您的接口使用者无法访问具体的类,这是首先拥有接口的一个主要原因。
回答by jpalecek
If you're talking about Java (but rules for other languages are similar), it is like this:
如果您在谈论 Java(但其他语言的规则类似),则是这样的:
You can (down)cast an interface to a concrete implementation, iff the reference you cast actually is a reference to the specific concrete implementation. That means
您可以(向下)将接口转换为具体实现,如果您转换的引用实际上是对特定具体实现的引用。这意味着
Vehicle v=new Car();
(Car)v // this is OK
(Bus)v // this is not
The error manifests itself as ClassCastException
in Java.
该错误ClassCastException
在 Java 中表现出来。
You can upcast a concrete implementation of an interface to the interface freely.
您可以自由地将接口的具体实现向上转换为接口。
回答by Steve Rowe
In most languages you can cast both directions. If you have a concrete class, you can cast it to the interface. If you have an interface, it is possible to cast to the concrete class.
在大多数语言中,您可以双向投射。如果你有一个具体的类,你可以将它转换为接口。如果您有接口,则可以转换为具体类。
Generally, you only want to go in the first direction. The reason being that you shouldn't know what the concrete class is when you have only a pointer to the interface. If you are passing something around as an interface, you should be able to do whatever you need to from that interface. If you find yourself needing to use parts of the concrete object not on the interface, you have a design problem that should be fixed instead of casting.
通常,您只想朝第一个方向前进。原因是当您只有一个指向接口的指针时,您不应该知道具体类是什么。如果您将某些东西作为接口传递,您应该能够从该接口执行您需要的任何操作。如果您发现自己需要使用不在界面上的具体对象的部分,那么您就有了一个应该修复而不是铸造的设计问题。
回答by Walter Verhoeven
An Interface canbe the whole class, if however doesn't have tobe, it is better when you create a constructor that accepts the Interface as Parameter and copy the Settings, this way you have control over what happens and what is needed.
接口可以是整个类,但如果不是必须是,最好创建一个接受接口作为参数的构造函数并复制设置,这样您就可以控制发生的事情和需要的内容。