C#返回不同的types?

我有这样的东西:

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?! } 

我有一个方法,这种方法有时会返回不同types的值(类)。

我怎么能做到这一点,当然以后的工作与variables,是radio.Play(); 到目前为止?

我需要使用generics吗? 怎么样?

如果没有公共基types或接口,那么public object GetAnything() {...} – 但通常最好是具有某种抽象,如通用接口。 例如,如果HelloComputerRadio都实现了IFoo ,那么它可以返回一个IFoo

下面是你如何用generics来做到这一点:

 public T GetAnything<T>() { T t = //Code to create instance return t; } 

但是你必须知道你想在devise时返回什么types。 这意味着你可以为每个创build调用不同的方法…

马克的答案应该是正确的,但在.NET 4中,你不能同时使用dynamictypes。

只有当你无法控制你返回的类并且没有共同的祖先时(通常使用interop),并且只有在不使用dynamic的时候,才会使用这个方法。

很less有博客文章试图解释何时使用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 } 

如果你可以为所有的可能性做一个抽象类,那么强烈build议:

 public Hardware GetAnything() { Computer computer = new Computer(); return computer; } abstract Hardware { } class Computer : Hardware { } 

或者一个界面:

 interface IHardware { } class Computer : IHardware { } 

如果它可以是任何东西,那么你可以考虑使用“对象”作为你的返回types,因为每个类派生自对象。

 public object GetAnything() { Hello hello = new Hello(); return hello; } 

要使用genericsbuild立@RQDQ的答案,可以将其与Func<TResult> (或一些变体)结合使用,并将责任委托给调用者:

 public T GetAnything<T>(Func<T> createInstanceOfT) { //do whatever return createInstanceOfT(); } 

然后你可以做一些事情:

 Computer comp = GetAnything(() => new Computer()); Radio rad = GetAnything(() => new Radio()); 

您可以使返回types成为三个类的超类(由您定义或仅使用object )。 然后你可以返回这些对象中的任何一个,但是在得到结果时你需要把它转换回正确的types。 喜欢:

 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?! } 

然后:

 Hello hello = (Hello)getAnything(); 

你可以返回一个Object,因为所有types都是从Objectinheritance的。

 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?! } 

然后你可以转换成相关的types:

 Hello hello = (Hello)GetAnything(); 

如果你不知道types是什么,那么你可以使用is关键字。

 Object obj = GetAnything(); if (obj is Hello) { // Do something } 

这就是说我不愿意写这样的代码。 有一个由你的每个类实现的接口会好得多。

 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(); } 

并让你的每个类都实现这个接口:

 public class Hello : ISpeak { void Speak() { Console.WriteLine("Hello"); } } 

然后你可以做这样的事情:

 GetAnything().Speak(); 

根据您要返回不同types的原因,您有几个选项。

a)你可以返回一个对象,调用者可以将它(可能在types检查之后)转换为他们想要的。 这当然意味着你失去了很多静态types的优点。

b)如果返回的types都有一个共同的“要求”,那么你可能会使用generics与constriants 。

c)在所有可能的返回types之间创build一个通用接口,然后返回接口。

d)切换到F#并使用模式匹配和区分的联合。 (对不起,稍微舌头检查!)

让方法从一个公共基类或接口返回一个对象。

 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(); } } 

里克的解决scheme是大多数情况下“最好的”方式。 有时候,当你不想使用对象作为基本types的时候。 你可以使用这样的方法:

 public object GetAnything() { Hello hello = new Hello(); Computer computer = new Computer(); Radio radio = new Radio(); return hello; // or computer or radio } 

要使用它,你会想要使用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 } } 

在你的情况下,你想调用一个方法播放。 所以这似乎更合适:

 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 } 

我有一个想法返回多种types…….

 public object GetAnything(object o) { Hello hello = new Hello(); Computer computer = new Computer(); Radio radio = new Radio(); if(o == Hello){return hello;} if(o == Computer {return computer;} if(o == Radio) {return radio;} } 

你可以使用外部类,根据需要设置属性types,然后在你的函数中使用它。

 public class MultipleOpjects { private List<string> _ObjectOne; public List<string> ObjectOne { get { return _ObjectOne; } set { _ObjectOne = value; } } private List<object> _ObjectTwo; public List<object> ObjectTwo { get { return _ObjectTwo; } set { _ObjectTwo = value; } } private object _ObjectThree; public object ObjectThree { get { return _ObjectThree; } set { _ObjectThree = value; } } } public MultipleOpjects GetAnything() { MultipleOpjects Vrble = new MultipleOpjects(); Vrble.ObjectOne = SomeThing1; Vrble.ObjectTwo = SomeThing2; Vrble.ObjectThree = SomeThing3; return Vrble; } 

为所有人定义单一types并不总是可能的。 即使可以的话,实施也很难。 我更喜欢使用参数。 唯一需要注意的是,你需要知道所有的高级返回types:

 public void GetAnything(out Hello h, out Computer c, out Radio r) { /// I suggest to: h = null; c = null; r = null; // first, // Then do whatever you have to do: Hello hello = new Hello(); Computer computer = new Computer(); Radio radio = new Radio(); } 

返回types可以是void或其他types,比如bool int或预定义的enum ,这可以帮助您检查exception或不同情况,无论使用何种方法。

可能你需要“dynamic”types?

 public dynamic GetAnything() { Hello hello = new Hello(); Computer computer = new Computer(); Radio radio = new Radio(); return /*what boject you needed*/ ;`enter code here` }