0

I thought that a base class would be an acceptable return signature but .Net Core 2.2 using visual studio code does not like it.

public class BasicRisk
{        
    public string Name {get;set;}
    public string Amount{get;set;}
}

public class LowRisk : BasicRisk
{
    public string Minimum { get; set; }
}

public class HighRisk : BasicRisk
{
    public string Risk { get; set; }
}

Now at some level this is working because I can mock populate data like this.

public class MockRiskkData
{
    private readonly List<HighRisk> _high = new List<HighRisk>();

    public MockRiskkData()
    {
       _all.Add(
            new HighRisk
            {
                Amount = "9384",
                Name = "Johnny Dangerous",
                Risk = "Extreme"
            }
        );
     }
}

However when I use the Baseclass as return value in a method signature I get can't explicitly convert error. Now my understanding was that any inherited class that uses the base class will satisfy the return signature.

public class MockRiskkData
{
    private readonly List<HighRisk> _high = new List<HighRisk>();
    private readonly List<LowRisk> _low = new List<LowRisk>();

    public MockRiskkData()
    {
       _all.Add(
            new HighRisk
            {
                Amount = "9384",
                Name = "Johnny Dangerous",
                Risk = "Extreme"
            }
        );
     }


    public Task<List<BasicRisk>> GetRiskAsync(int risktype)
    {
        if(risktype == 1)
        {
            return Task.FromResult(_high); //Cannot implicitly convert type
        }

        return Task.FromResult(_low); //Cannot implicitly convert type
    }

}

So clearly I am incorrect in my understanding. What can I try next?

halfer
  • 19,824
  • 17
  • 99
  • 186
GPGVM
  • 5,515
  • 10
  • 56
  • 97
  • Might be the same issue but I removed the task wrapper and tried just a List and same issue. – GPGVM Feb 21 '19 at 21:37
  • Same issue. It's described in the accepted answer of linked question. – Zer0 Feb 21 '19 at 21:38
  • 2
    [A `List` can't be implicitly converted to a `List`.](https://stackoverflow.com/questions/25792563/how-to-correctly-cast-a-class-to-an-abstract-class-when-using-type-generics/25792782#25792782) – Zohar Peled Feb 21 '19 at 21:40
  • By the way, the reason you can't case a list of derived to a list of base can be seen in the typical `Animal`, `Dog`, `Cat` class hierarchy. If you have a `List` and you casted it to a `List`, then someone could add a `Cat` to the list (since Cats are animals too). At that point, one of your `Dog`s would be a `Cat` and bad things would happen. – Flydog57 Feb 21 '19 at 21:47
  • This is a duplicate. Thanks for the help. – GPGVM Feb 21 '19 at 21:55

1 Answers1

0

It is not possible to convert Task<Derived> to Task<Base> implicitly. however you can use extension method to make conversion.

public static Task<TBase> ConvertToBaseTask<TDerived, TBase>(this Task<TDerived> task, CancellationToken cancellationToken = default) 
    where TBase : class 
    where TDerived : TBase
{
    var result = task.ContinueWith(t => t.Result as TBase, cancellationToken);
    return result;
}
Derviş Kayımbaşıoğlu
  • 28,492
  • 4
  • 50
  • 72