Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/261.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 返回不同的类型?_C#_Types - Fatal编程技术网

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
an
int
或预定义的
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;