C# Return Different Types?

后端 未结 15 2045
无人及你
无人及你 2020-12-08 09:11

I got something like this:

public [What Here?] GetAnything()
{
     Hello hello = new Hello();
     Computer computer = new Computer();
     Radio radio = ne         


        
相关标签:
15条回答
  • 2020-12-08 09:53

    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());
    
    0 讨论(0)
  • 2020-12-08 09:53

    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();
      }
    }
    
    0 讨论(0)
  • 2020-12-08 09:53

    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!");
    }
    
    0 讨论(0)
  • 2020-12-08 09:55

    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, Computer and Radio all implemented IFoo, then it could return an IFoo.

    0 讨论(0)
  • 2020-12-08 09:56

    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   
    }
    
    0 讨论(0)
  • 2020-12-08 09:58

    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

    0 讨论(0)
提交回复
热议问题