C# 返回不同的类型?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8986975/
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
C# Return Different Types?
提问by eMi
I got something like this:
我得到了这样的东西:
public [What Here?] GetAnything()
{
Hello hello = new Hello();
Computer computer = new Computer();
Radio radio = new Radio();
return radio; or return computer; or return hello //should be possible?!
}
I have a Method and this method returns me sometimes different Types of Values (classes).
我有一个方法,这个方法有时会返回不同类型的值(类)。
How can I do this anyway and ofcourse later to work with the variables, b.e radio.Play(); and so far?
无论如何我怎么能做到这一点,当然以后要使用变量,是 radio.Play(); 到目前为止?
Do I need to use generics? How?
我需要使用泛型吗?如何?
采纳答案by Marc Gravell
If there is no common base-type or interface, then public object GetAnything() {...}- but it would usually be preferable to have some kind of abstraction such as a common interface. For example if Hello, Computerand Radioall implemented IFoo, then it could return an IFoo.
如果没有通用的基类型或接口,那么public object GetAnything() {...}- 但通常最好有某种抽象,例如通用接口。例如,如果Hello,Computer并且Radio全部实现IFoo,那么它可以返回一个IFoo.
回答by Tudor
You can have the return type to be a superclass of the three classes (either defined by you or just use object). Then you can return any one of those objects, but you will need to cast it back to the correct type when getting the result. Like:
您可以将返回类型设为三个类的超类(由您定义或仅使用object)。然后您可以返回这些对象中的任何一个,但是在获得结果时您需要将其转换回正确的类型。喜欢:
public object GetAnything()
{
Hello hello = new Hello();
Computer computer = new Computer();
Radio radio = new Radio();
return radio; or return computer; or return hello //should be possible?!
}
Then:
然后:
Hello hello = (Hello)getAnything();
回答by Rick Kuipers
If you can make a abstract class for all the possibilities then that is highly recommended:
如果您可以为所有可能性创建一个抽象类,那么强烈建议您这样做:
public Hardware GetAnything()
{
Computer computer = new Computer();
return computer;
}
abstract Hardware {
}
class Computer : Hardware {
}
Or an interface:
或者一个接口:
interface IHardware {
}
class Computer : IHardware {
}
If it can be anything then you could consider using "object" as your return type, because every class derives from object.
如果它可以是任何东西,那么您可以考虑使用“对象”作为您的返回类型,因为每个类都从对象派生。
public object GetAnything()
{
Hello hello = new Hello();
return hello;
}
回答by RQDQ
Here is how you might do it with generics:
以下是您可以如何使用泛型做到这一点:
public T GetAnything<T>()
{
T t = //Code to create instance
return t;
}
But you would have to know what type you wanted returned at design time. And that would mean that you could just call a different method for each creation...
但是你必须知道你想要在设计时返回什么类型。这意味着您可以为每个创建调用不同的方法......
回答by Vasya
May be you need "dynamic" type?
您可能需要“动态”类型吗?
public dynamic GetAnything()
{
Hello hello = new Hello();
Computer computer = new Computer();
Radio radio = new Radio();
return /*what boject you needed*/ ;`enter code here`
}
回答by tbt
Marc's answer should be the correct one, but in .NET 4 you couldn't also go with dynamic type.
Marc 的答案应该是正确的,但是在 .NET 4 中,您也不能使用动态类型。
This should be used only if you have no control over the classes you return and there are no common ancestors ( usually with interop ) and only if not using dynamic is a lot more painful then using(casting every object in every step :) ).
仅当您无法控制返回的类并且没有共同的祖先(通常使用 interop )并且仅当不使用 dynamic 比使用(在每个步骤中投射每个对象:) 更痛苦时才应该使用它)。
Few blog post trying to explain when to use dynamic: http://blogs.msdn.com/b/csharpfaq/archive/tags/dynamic/
很少有博客文章试图解释何时使用动态:http: //blogs.msdn.com/b/csharpfaq/archive/tags/dynamic/
public dynamic GetSomething()
{
Hello hello = new Hello();
Computer computer = new Computer();
Radio radio = new Radio();
return // anyobject
}
回答by mavnn
You have a few options depending on why you want to return different types.
根据您想要返回不同类型的原因,您有几个选项。
a) You can just return an object, and the caller can cast it (possibly after type checks) to what they want. This means of course, that you lose a lot of the advantages of static typing.
a) 你可以只返回一个对象,调用者可以将它(可能在类型检查之后)转换为他们想要的。这当然意味着您失去了静态类型的许多优点。
b) If the types returned all have a 'requirement' in common, you might be able to use generics with constriants.
b) 如果返回的类型都有一个共同的“要求”,您也许可以使用带有约束的泛型。
c) Create a common interface between all of the possible return types and then return the interface.
c) 在所有可能的返回类型之间创建一个公共接口,然后返回该接口。
d) Switch to F# and use pattern matchingand discriminated unions. (Sorry, slightly tongue in check there!)
d) 切换到 F# 并使用模式匹配和可区分联合。(对不起,在那里稍微检查一下舌头!)
回答by Glenn
Let the method return a object from a common baseclass or interface.
让该方法从公共基类或接口返回一个对象。
public class TV:IMediaPlayer
{
void Play(){};
}
public class Radio:IMediaPlayer
{
void Play(){};
}
public interface IMediaPlayer
{
void Play():
}
public class Test
{
public void Main()
{
IMediaPlayer player = GetMediaPlayer();
player.Play();
}
private IMediaPlayer GetMediaPlayer()
{
if(...)
return new TV();
else
return new Radio();
}
}
回答by Joe Axon
You could just return an Object as all types are descended from Object.
您可以只返回一个 Object,因为所有类型都来自 Object。
public Object GetAnything()
{
Hello hello = new Hello();
Computer computer = new Computer();
Radio radio = new Radio();
return radio; or return computer; or return hello //should be possible?!
}
You could then cast to its relevant type:
然后,您可以转换为其相关类型:
Hello hello = (Hello)GetAnything();
If you didn't know what the type was going to be then you could use the iskeyword.
如果您不知道类型将是什么,那么您可以使用is关键字。
Object obj = GetAnything();
if (obj is Hello) {
// Do something
}
This being said I would be reluctant to write code like that. It would be much better to have an interface which is implemented by each of your classes.
话虽如此,我不愿意写那样的代码。拥有一个由您的每个类实现的接口会好得多。
public ISpeak GetAnything()
{
Hello hello = new Hello();
Computer computer = new Computer();
Radio radio = new Radio();
return radio; or return computer; or return hello //should be possible?!
}
interface ISpeak
{
void Speak();
}
and have each of your classes implement the interface:
并让您的每个类实现接口:
public class Hello : ISpeak
{
void Speak() {
Console.WriteLine("Hello");
}
}
You could then do something like:
然后,您可以执行以下操作:
GetAnything().Speak();
回答by Aidiakapi
Rick's solution is the 'best' way to go in most cases. Sometimes when that's not available you want to use object as base type. And you could use the method like this:
在大多数情况下,Rick 的解决方案是“最佳”方式。有时,当它不可用时,您想使用 object 作为基本类型。你可以使用这样的方法:
public object GetAnything()
{
Hello hello = new Hello();
Computer computer = new Computer();
Radio radio = new Radio();
return hello; // or computer or radio
}
To use it, you will want to use the asoperator, like this:
要使用它,您需要使用as运算符,如下所示:
public void TestMethod()
{
object anything = GetAnything();
var hello = anything as Hello;
var computer = anything as Computer;
var radio = anything as Radio;
if (hello != null)
{
// GetAnything() returned a hello
}
else if (computer != null)
{
// GetAnything() returned a computer
}
else if (radio != null)
{
// GetAnything() returned a radio
}
else
{
// GetAnything() returned... well anything :D
}
}
In your case you want to call a method play. So this'd seem more appropriate:
在您的情况下,您想调用方法播放。所以这似乎更合适:
interface IPlayable
{
void Play();
}
class Radio : IPlayable
{
public void Play() { /* Play radio */ }
}
class Hello : IPlayable
{
public void Play() { /* Say hello */ }
}
class Computer : IPlayable
{
public void Play() { /* beep beep */ }
}
public IPlayable GetAnything()
{
Hello hello = new Hello();
Computer computer = new Computer();
Radio radio = new Radio();
return hello; // or computer or radio
}

