[c#] C# Return Different Types?

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?

Do I need to use generics? How?

This question is related to c# types

The answer is


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`   
}

Defining a single type for all is not always possible. Even if when you can, the implementation is rarely easy. I prefer to use out parameters. The only caveat is that you need to know all the return types in 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();
}

The return type can be a void, or something else, like bool an int or a predefined enum which can help you check for exceptions or different cases wherever the method is used.


To build on the answer by @RQDQ using generics, you can combine this with Func<TResult> (or some variation) and delegate responsibility to the caller:

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

    return createInstanceOfT();
}

Then you can do something like:

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

It's a sample using Generic Types.

public T GetAnything<T>() where T : class, new()
    => new T();

And you'll use this method calling this way:

var hello = GetAnything<Hello>();

In this case, you can use an interface to specify a type to pass as parameter.

public T GetAnything<T>() where T : ISomeInterface, new()
    => new T();

You must have a parameterless construtor in each class to use new() constraint.

Follow the full sample:

internal sealed class Program
{
    private static void Main(string[] args)
    {
        GetAnything<Hello>().Play();
        GetAnything<Radio>().Play();
        GetAnything<Computer>().Play();
    }

    private static T GetAnything<T>() where T : ISomeInterface, new()
        => new T();
}

internal interface ISomeInterface
{
    void Play();
}

internal sealed class Hello : ISomeInterface
{
    // parameterless constructor.
    public Hello() { }
    public void Play() => Console.WriteLine("Saying hello!");
}

internal sealed class Radio : ISomeInterface
{
    // parameterless constructor.
    public Radio() { }
    public void Play() => Console.WriteLine("Playing radio!");
}

internal sealed class Computer : ISomeInterface
{
    // parameterless constructor.
    public Computer() { }
    public void Play() => Console.WriteLine("Playing from computer!");
}

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.

b) If the types returned all have a 'requirement' in common, you might be able to use generics with constriants.

c) Create a common interface between all of the possible return types and then return the interface.

d) Switch to F# and use pattern matching and discriminated unions. (Sorry, slightly tongue in check there!)


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

Marc's answer should be the correct one, but in .NET 4 you couldn't also go with dynamic type.

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 :) ).

Few blog post trying to explain when to use 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

}

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...


You could just return an Object as all types are descended from 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 is keyword.

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

use the dynamic keyword as return type.

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

// dynamic keyword is preferable to use in this case instead of an object type

// because dynamic keyword keeps the underlying structure and data type so that // you can directly inspect and view the value.

// in object type, you have to cast the object to a specific data type to view // the underlying value.

regards,

Abhijit


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:

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 as operator, like this:

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   
}

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:

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

You could use external class, set the properties types as you wish, then use it in your function.

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

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

My post here is strictly related to Blazor v5 but should work in 3.x as well. Additionally, I'm using these methods with bootstrap 4.5 and 5.0 beta 1 but you could easily adapt it to use style's instead of classes or use your own classes.

To those recommending dynamic, I thank you. The dynamic type seems like it can be very valuable when used correctly. Most of the time you'll probably use an interface but this wasn't plausible for me. I went ahead and updated my project with a dynamic return type and it's working great while being the quickest, cleanest solution.

I previously added the following extension methods to boolean types to help me avoid long ternary operators in razor page code. Here are the 3 main extension methods I use to accomplish it:

public static T Then<T>(this bool value, T result) => value ? result : default;    
public static T Then<T>(this bool value, T thenResult, T elseResult) => value ? thenResult : elseResult;
public static T Else<T>(this bool value, T result) => !value ? result : default;

The following are examples of that implementation:

<div class="@Hidden.Then("d-none")">
    Hidden content...
</div>

Note: ErrorOrWarning would hide the content if there was no error/warning so I could default it to yellow/italic but this is an example so please use your imagination:

<div class="@ErrorOrWarning.Else("d-none")" style="@Error.Then("color:red;font-weight:bold;","color:yellow;font-style:italic;")">
    Error/Warning content...
</div>

This is the typical implementation without the extension methods. It's common to see this technique in Blazor guides/tutorials/videos online. There are cleaner ways to handle it but this is the basic idea:

<div class="@(ErrorOrWarning ? "" : "d-none")" style="@(Error ? "color:red;font-weight:bold;" : "color:yellow;font-style:italic;")">
    Error/Warning content...
</div>

While this might not seem like too big a difference, if you have a lot of dynamic content/styles driving your page, it can get really messy. With those 3 lines of code you can enhance the readability and cleanliness and it really does reduce risk of typos. Adding two more extension methods, you can reduce the risk even further Note: Again, this is using bootstrap class "d-none" for the style "display:none!important" but you could just as easily replace with your own usage:

public static string ThenShow(this bool value) => value ? "" : "d-none";
public static string ThenHide(this bool value) => value ? "d-none" : "";

The limitation I previously faced was when using the overloaded Then(thenResult, elseResult), each of the parameters must be of the same type. 99% of the time this is fine. Actually, another 0.5% of the time it's still okay because you can probably solve it quickly with a .ToString() or an explicit cast.

What I ran into, and what took me to this post was: I have a control you can imagine as a button. There is an Enum property allowing the user to select an icon to display. The selected Enum dynamically populates a readonly MarkupString property. As an alternative option, they can use the ChildContent (or IconContent in my example) of type RenderFragment. This will let them manually add anything they want (maybe an iFrame to stackoverflow haha) but my intention is for them to add style, most likely in the form of an icon.

I know I can cast/convert one to the other however my existing extension method is so clean and simple, it would be great to be able to use pass the MarkupString and RenderFragment together as parameters, conditionally output to the razor page. So, thanks to this post, I changed my Then(thenResult, elseResult) extension methods to use unique generic parameter types and return a dynamic type like so:

public static dynamic Then<T,E>(this bool value, T thenResult, E elseResult) => value ? thenResult : elseResult;

Now in my razor page I have a very simple line for the icon output. Note: IconContent is a RenderFragment and IconMarkup is a MarkupString.

@((@IconContent == null).Then(IconMarkup, IconContent))

And because I love extension methods and I'm typing this up, I took it a step further with another extension method:

public static bool IsNull(this RenderFragment value) => value == null;

Which enables the extremely clean and simple:

@IconContent.IsNull().Then(IconMarkup, IconContent)

Here's the extra extension method I mentioned above which converts a string to a MarkupString. It might be overkill but I like it.

public static MarkupString ToMarkup(this string value) => (MarkupString)value;

Let me know if you have a better recommendation or if you think I'm doing something wrong. I'm sure this post makes it seem like I overuse extension methods but I really don't. I keep their use limited to outcomes such as I've outlined in this post.