Reputation: 1199
I am trying to set a value on a base class but am getting the error:
Cannot implicitly convert type
'PersonService'
to'IMyInterface<IEntity>'
. An explicit conversion exists (are you missing a cast?)
When I try to create my PersonService()
it does implement IMyInterface<Person>
. Person implements IEntity
so I can't work out why it is not working.
public interface IEntity { }
public class Person : IEntity { }
public interface IMyInterface<T> where T : IEntity { }
public class PersonService : IMyInterface<Person> { }
public abstract class Model : IEntity
{
public IMyInterface<IEntity> DataService { get; set; }
}
public class Test : Model
{
public Person Person { get; set; }
public Test() : base()
{
DataService = new PersonService();
}
}
Upvotes: 0
Views: 2224
Reputation: 136074
Because DataService
is expecting an IMyInterface<IEntity>
not an IMyInterface<Person>
.
Other answers regarding covariance are a great way to solve this - another is to introduce some generics.
If you change Model
like this to specify the type of entity
public abstract class Model<TEntity> : IEntity
where TEntity : IEntity
{
public IMyInterface<TEntity> DataService { get; set; }
}
and Test
like this:
public class Test : Model<Person>
{
public Person Person { get; set; }
public Test() : base()
{
DataService = new PersonService();
}
}
All works as expected:
http://rextester.com/EVBT53292
Upvotes: 0
Reputation: 28759
An IMyInterface<Person>
isn't necessarily compatible with an IMyInterface<IEntity>
. What if IMyInterface
contains an .Add(T item)
method? If you were allowed to call that through IMyInterface<IEntity>
for something that's not a Person
, the collection would end up with an invalid element, violating type safety.
But what if IMyInterface
contains no such methods, and it's always safe? In that case you can tell the compiler that by using a covariant type:
public interface IMyInterface<out T> where T : IEntity { }
And now your example will compile.
Upvotes: 5
Reputation: 15982
You need to make your interface co-variant (if it's possible):
public interface IMyInterface<out T> where T : IEntity { }
Then you would be able to do:
DataService = new PersonService();
Upvotes: 2