Question

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();
Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top