C# 返回不同的类型?
我得到了这样的东西:C# 返回不同的类型?,c#,types,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?! } public obj
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?!
}
public object GetAnything()
{
Hello hello = new Hello();
Computer computer = new Computer();
Radio radio = new Radio();
return hello; // or computer or radio
}
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
}
}
我有一个方法,这个方法有时会返回不同类型的值(类)
无论如何,我怎样才能做到这一点?当然,稍后我如何处理变量b.e radio.Play();到目前为止呢
我需要使用泛型吗?怎么做?如果没有公共基类型或接口,那么
公共对象GetAnything(){…}
-但是通常最好有某种抽象,比如公共接口。例如,如果Hello
、Computer
和Radio
都实现了IFoo
,那么它可以返回一个IFoo您可以将返回类型设置为三个类的超类(由您定义或仅使用对象
)。然后,您可以返回这些对象中的任何一个,但在获得结果时需要将其转换回正确的类型。比如:
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?!
}
然后:
如果您可以为所有可能性创建一个抽象类,那么强烈建议您:
public Hardware GetAnything()
{
Computer computer = new Computer();
return computer;
}
abstract Hardware {
}
class Computer : Hardware {
}
或接口:
interface IHardware {
}
class Computer : IHardware {
}
public class Hello : ISpeak
{
void Speak() {
Console.WriteLine("Hello");
}
}
如果它可以是任何东西,那么你可以考虑使用“对象”作为你的返回类型,因为每一个类都是从对象派生的。
public object GetAnything()
{
Hello hello = new Hello();
return hello;
}
下面是使用泛型的方法:
public T GetAnything<T>()
{
T t = //Code to create instance
return t;
}
public T GetAnything()
{
T=//创建实例的代码
返回t;
}
但您必须知道在设计时希望返回什么类型。这意味着您可以为每个创建调用不同的方法…您可能需要“动态”类型吗
Marc的答案应该是正确的,但在.NET4中,您不能同时使用动态类型
只有当您无法控制返回的类并且没有公共祖先(通常是互操作)时,才应使用此选项,并且只有当不使用动态比使用(在每个步骤中强制转换每个对象:)更痛苦时才应使用此选项。
很少有博客文章试图解释何时使用dynamic:
根据返回不同类型的原因,您有几个选项
a) 您只需返回一个对象,调用方就可以(可能在类型检查之后)将其强制转换为所需的对象。当然,这意味着您将失去很多静态类型的优点
b) 如果返回的所有类型都有一个共同的“需求”,那么您可以使用
c) 在所有可能的返回类型之间创建一个公共接口,然后返回接口
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();
}
}
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();
}
}
您可以只返回一个对象,因为所有类型都是对象的后代
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();
如果您不知道类型是什么,那么可以使用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();
}
并让每个类实现接口:
interface IHardware {
}
class Computer : IHardware {
}
public class Hello : ISpeak
{
void Speak() {
Console.WriteLine("Hello");
}
}
然后,您可以执行以下操作:
GetAnything().Speak();
Computer comp = GetAnything(() => new Computer());
Radio rad = GetAnything(() => new Radio());
在大多数情况下,Rick的解决方案是“最好”的方法。有时,当这不可用时,您希望使用对象作为基本类型。你可以使用这样的方法:
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?!
}
public object GetAnything()
{
Hello hello = new Hello();
Computer computer = new Computer();
Radio radio = new Radio();
return hello; // or computer or radio
}
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
}
}
要使用它,您需要使用as
操作符,如下所示:
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?!
}
public object GetAnything()
{
Hello hello = new Hello();
Computer computer = new Computer();
Radio radio = new Radio();
return hello; // or computer or radio
}
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
}
}
在您的例子中,您希望调用一个方法play。所以这看起来更合适:
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
}
您可以使用外部类,根据需要设置属性类型,然后在函数中使用它
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;
}
公共类多项目
{
私人名单(ObjectOne),;
公共列表ObjectOne{
获取{return\u ObjectOne;}
设置{u ObjectOne=value;}
}
私人名单(二),;
公共列表对象二{
获取{return\u ObjectTwo;}
设置{u ObjectTwo=value;}
}
私有对象_object三;
公共对象对象对象三{
获取{return}
设置{u ObjectThree=value;}
}
}
公共多项目GetAnything()
{
多项目Vrble=新的多项目();
Vrble.ObjectOne=SomeThing1;
Vrble.ObjectTwo=SomeThing2;
Vrble.ObjectThree=某物3;
返回Vrble;
}
要在@RQDQ使用泛型的基础上构建答案,您可以将其与Func
(或某些变体)相结合,并将责任委托给调用方:
public T GetAnything<T>(Func<T> createInstanceOfT)
{
//do whatever
return createInstanceOfT();
}
为所有人定义单一类型并不总是可能的。即使可以,实现也很少容易。我更喜欢使用out
参数。唯一需要注意的是,您需要了解advanced中的所有返回类型:
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();
}
返回类型可以是void
,也可以是其他类型,如bool
anint
或预定义的enum
,它可以帮助您在使用该方法的任何位置检查异常或不同情况。使用动态关键字作为返回类型
private dynamic getValuesD<T>()
{
if (typeof(T) == typeof(int))
{
return 0;
}
else if (typeof(T) == typeof(string))
{
return "";
}
else if (typeof(T) == typeof(double))
{
return 0;
}
else
{
return false;
}
}
int res = getValuesD<int>();
string res1 = getValuesD<string>();
double res2 = getValuesD<double>();
bool res3 = getValuesD<bool>();
private动态getValuesD()
{
if(typeof(T)=typeof(int))
{
返回0;
}
else if(typeof(T)=typeof(string))
{
返回“”;
}
否则如果(类型(T)=类型(双))
{
返回0;
}
其他的
{
返回false;
}
}
int res=getValuesD();
字符串res1=getValuesD();
double res2=getValuesD();
bool res3=getValuesD();
//在这种情况下,最好使用dynamic关键字,而不是对象类型
//因为dynamic关键字保留了底层结构和数据类型,所以//您可以直接检查和查看值
//在对象类型中,必须将对象强制转换为特定的数据类型,才能查看//基础值
问候,
Abhijit这是一个使用泛型类型的示例
public T GetAnything<T>() where T : class, new()
=> new T();
public T GetAnything(),其中T:class,new()
=>新的T();
您将使用以下方法调用:
var hello = GetAnything<Hello>();
var hello=GetAnything();
<
public static string ThenShow(this bool value) => value ? "" : "d-none";
public static string ThenHide(this bool value) => value ? "d-none" : "";
public static dynamic Then<T,E>(this bool value, T thenResult, E elseResult) => value ? thenResult : elseResult;
@((@IconContent == null).Then(IconMarkup, IconContent))
public static bool IsNull(this RenderFragment value) => value == null;
@IconContent.IsNull().Then(IconMarkup, IconContent)
public static MarkupString ToMarkup(this string value) => (MarkupString)value;