Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Cannot Convert from error in simple class structure

I have the following class relationships

    public interface ICapability
    {
    }

    public interface IBaseService<T> where T : ICapability
    {
    }

    public abstract class BaseService<out T> : IBaseService<T> where T : ICapability
    {
       // modified...
       T MapEventToCapability(dynamic eventData, T capability);
    }

    public class SomeCapability : ICapability
    {
    }

    public partial class Service1 : BaseService<SomeCapability>
    {
        public Service1()
        {
        }
    }

    public class ServiceResolver 
    {
        public void Register(BaseService<ICapability> serviceToRegister)
        {
        }
    }

I try to invoke the Register method, passing in a new service1 as shown:

var b = new ServiceResolver();
var c = new Service1();

b.Register(c);

However I get a compile time error on c in the call to Register as follows;

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Cannot convert Service1 to BaseService<ICapability>

I assumed that because Service1 is of type BaseService and that since SomeCapability is of type ICapability that this wouldn’t be an issue.

I tried casting to BaseService as well I tried changing the input parameter on Register to be an IBaseService and again casting but then I get a runtime error.

>Solution :

Note the question has been updated since this answer was posted – covariance is no longer an option having added a method which is incompatible


You’ll need to do 2 things to make this work

  1. Make Register take IBaseService<ICapability> not BaseService<ICapability>
  2. Make IBaseService covariant by marking the generic type as out – this is the same as the reason you can pass a List<Foo> to a merthod which expects an IEnumerable<Foo> as IEnumerable<T> is covariant in a similar manner.

public class ServiceResolver
{
    public void Register(IBaseService<ICapability> serviceToRegister)
    {
    }
}

and

public interface IBaseService<out T>
    where T : ICapability
{
}

Live example: https://dotnetfiddle.net/O0yXa5

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading