Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No implicit reference conversion error between generic interface concrete type

I am using Unity to resolve a generic interface to a concrete type that implements that interface:

_container.RegisterType<IItemLocatorFactory<Job, ILocatorViewModel<Job>>,
            ItemLocatorFactory<Job, BaseJobViewModel>>();

The declaration of IItemLocatorFactory<Job, ILocatorViewModel<Job>> is:

public interface IItemLocatorFactory<TData, TModel> 
    where TData : IMyEntity
    where TModel : ILocatorViewModel<TData>

The class ItemLocatorFactory<Job, BaseJobViewModel> implements the interface IItemLocatorFactory<Job, ILocatorViewModel<Job>:

public class ItemLocatorFactory<T, TModel> : IItemLocatorFactory<T, TModel>
    where T : IMyEntity
    where TModel : ILocatorViewModel<T>

The class BaseJobViewModel is declared like this:

public class BaseJobViewModel : ILocatorViewModel<Job>

But this gives me compile error complaining that there is no implicit reference conversion:

Error 1 The type 'UI.ItemLocator.Infrastructure.DefaultItemLocatorFactory.ItemLocatorFactory' cannot be used as type parameter 'TTo' in the generic type or method 'Microsoft.Practices.Unity.UnityContainerExtensions.RegisterType(Microsoft.Practices.Unity.IUnityContainer, params Microsoft.Practices.Unity.InjectionMember[])'. There is no implicit reference conversion from 'UI.ItemLocator.Infrastructure.DefaultItemLocatorFactory.ItemLocatorFactory' to 'Interfaces.UI.ItemLocator.IItemLocatorFactory>'.

What am I getting wrong here?

like image 646
AunAun Avatar asked Jan 28 '14 08:01

AunAun


1 Answers

You're using a different TModel in the interface and the implementation.

This is the same reason List<Derived> isn't castable to IList<Base> although List<T> is castable to IList<T> and Derived is castable to Base.

If you want ItemLocatorFactory<T, TModel> to be assignable to IItemLocatorFactory<T, TBaseModel> you need to make the interface's TBaseModel covariant by declaring it with out:

public interface IItemLocatorFactory<T, out TModel> 
{
  /* use TModel here in a covariant way */
}
like image 129
Avish Avatar answered Oct 25 '22 07:10

Avish