Home > Mobile >  Cannot convert IActivity<Animal> to IActivity<Dog>
Cannot convert IActivity<Animal> to IActivity<Dog>

Time:07-10

The only class we can modify is the generic Executor below. I want an executor of type Dog to be able to invoke not only an activity of type Dog but also an activity of type Animal.

My code below fails to do so

var executorDog = new Executor<Dog>();
var animalActivity = new AnimalActivity();
executorDog.Execute(animalActivity);

with the following error:

error CS1503: Argument 1: cannot convert from 'AnimalActivity' to 'IActivity<Dog>'

How to fix it?

using System;

class Animal { }
class Dog : Animal { }

interface IActivity<T>
{
    void Eat();
}

class Activity<T> : IActivity<T>
{
    public virtual void Eat() { }
}

class DogActivity : Activity<Dog>
{
    public override void Eat()
    {
        Console.WriteLine("Dog is eating...");
    }
}

class AnimalActivity : Activity<Animal>
{
    public override void Eat()
    {
        Console.WriteLine("Animal is eating...");
    }
}


interface IExecutor<T>
{
    void Execute(IActivity<T> activity);
}

class Executor<T> : IExecutor<T> where T : Animal
{
    public void Execute(IActivity<T> activity)
    {
        activity.Eat();
    }
}


class Program
{
    static void Main()
    {
        var executorDog = new Executor<Dog>();
        var animalActivity = new AnimalActivity();
        executorDog.Execute(animalActivity);
    }
}

CodePudding user response:

Maybe try this instead

class Executor<T> where T : Animal
{
    public void Execute(Activity<T> activity)
    {
        activity.Eat();
    }
}

Sorry for the short reply I'm on my phone

CodePudding user response:

It doesn't work because

  1. Executor<Derived> needs IActivity<Derived> and
  2. AnimalActivity gives it IActivity<Base>.

To be honest it is not clear what you're trying to achieve but you can make your code work by making Executor non-generic and accept IActivity<Base> (in your case IActivity<Animal>) (Which makes sense because the executor should not be a different class depending on what kind of activity it works with):

interface IExecutor
{
    void Execute(IActivity<Animal> activity);
}

class Executor : IExecutor
{
    public void Execute(IActivity<Animal> activity)
    {
        activity.Eat();
    }
}

Then

var executor = new Executor();
var animalActivity = new AnimalActivity();
executor.Execute(animalActivity);

will print

Animal is eating...
  •  Tags:  
  • c#
  • Related