I have a factory class with this method signature
public static PortfolioUnitOfWork<IPortfolio> GetPortfolioUnitOfWork(string supplier)
{
}
The PortfolioUnitOfWork
is a generic object, which can take different Portfolio types.
public class PortfolioUnitOfWork<T> :Abstracts.UnitOfWork<T> where T:class, Data.Interfaces.IPortfolio
{
}
The idea here, is a string is passed into the factory, from that string it could return PortfolioUnitOfWork<Type1>
or PortfolioUnitOfWork<Type2>
etc. Type1
and Type2
would inherit from IPortfolio
.
When trying to set return items for this factory class method, I have the error
cannot convert expression type PortfolioUnitOfWork<Type1> to return type PortfolioUnitOfWork<IPortfolio>
The IPortfolio interface has no methods, just a number of properties
public interface IPortfolio
{
int Id { get; set; }
string Name { get; set; }
....
}
The Portfolio types are EntityFramework Entities, but I have a partial class for each, in which the entity is inherited from the interface. They also have a few non-mapped properties as a result of that.
I would have thought using PortfolioUnitOfWork<IPortfolio>
as the return type would allow the factory class to return the correct PortfolioUnitOfWork as required. Any ideas why the error might occur?
//Edit
Strangely, in the Factory Class if I set the return type to
return new PortfolioUnitOfWork<IPortfolio>()
There is no immediate error showing in the IDE (didn't do a build though). I would have thought that would be invalid as T
inherits from class in the PortfolioUnitOfWork
class
This does not work either, same error.
PortfolioUnitOfWork<IPortfolio> porfolio = new PortfolioUnitOfWork<Type1>();
Something like this DOES work, showing the Type1
implements the correct interface
IPortfolio test = new Type1();
That's because generic types are invariant by default in c#. It means you cannot do following:
List<object> list = new List<string>();
or in your case
PortfolioUnitOfWork<IPortfolio> porfolio = new PortfolioUnitOfWork<Type1>();
And you can't do them variant, because in .NET only interface and delegate type parameters can be variant. Following error appears when you try:
Invalid variance modifier. Only interface and delegate type parameters can be specified as variant.
Possible way to go? Create IPortfolioUnitOfWork
:
public interface IPortfolioUnitOfWork
{ }
And change your PortfolioUnitOfWork<T>
to implement that:
public class PortfolioUnitOfWork<T> : IPortfolioUnitOfWork where T: class, IPortfolio
now you can do following:
IPortfolioUnitOfWork porfolio = new PortfolioUnitOfWork<Type1>();
ofc, you'll have to change your return statements and variable types from PortfolioUnitOfWork<IPortfolio>
to IPortfolioUnitOfWork
.