c# - 从工厂类返回派生类型

标签 c# interface entity-framework-5 factory-pattern

我有一个带有这个方法签名的工厂类

 public static PortfolioUnitOfWork<IPortfolio> GetPortfolioUnitOfWork(string supplier)
 {
 }

PortfolioUnitOfWork是一个通用对象,可以采用不同的 Portfolio 类型。

public class PortfolioUnitOfWork<T> :Abstracts.UnitOfWork<T> where T:class, Data.Interfaces.IPortfolio
{
}

这里的想法是,将一个字符串传递给工厂,它可以从该字符串返回 PortfolioUnitOfWork<Type1>PortfolioUnitOfWork<Type2>Type1Type2将从 IPortfolio 继承.

当试图为这个工厂类方法设置返回项时,出现错误

cannot convert expression type PortfolioUnitOfWork<Type1> to return type PortfolioUnitOfWork<IPortfolio>

IPortfolio 接口(interface)没有方法,只有一些属性

public interface IPortfolio
{
   int Id { get; set; }
   string Name { get; set; }
   ....
} 

投资组合类型是 EntityFramework 实体,但我为每个类型都有一个部分类,其中实体是从接口(interface)继承的。因此,它们也有一些未映射的属性。

我会想到使用 PortfolioUnitOfWork<IPortfolio>因为返回类型将允许工厂类根据需要返回正确的 PortfolioUnitOfWork。知道为什么会发生错误吗?

//编辑

奇怪的是,在工厂类中,如果我将返回类型设置为

return new PortfolioUnitOfWork<IPortfolio>()

IDE 中没有立即显示错误(虽然没有进行构建)。我原以为这将是无效的 T继承自 PortfolioUnitOfWork 中的类类

这也不行,同样的错误。

PortfolioUnitOfWork<IPortfolio> porfolio = new PortfolioUnitOfWork<Type1>();

这样的事情确实有效,显示了 Type1实现正确的接口(interface)

IPortfolio test = new Type1();

最佳答案

那是因为泛型类型是 invariant在 C# 中默认。这意味着您不能执行以下操作:

List<object> list = new List<string>();

或者在你的情况下

PortfolioUnitOfWork<IPortfolio> porfolio = new PortfolioUnitOfWork<Type1>();

而且您不能对它们进行变体,因为在 .NET 中,只有接口(interface)和委托(delegate)类型参数可以是变体。尝试时出现以下错误:

Invalid variance modifier. Only interface and delegate type parameters can be specified as variant.

可行的方法?创建IPortfolioUnitOfWork :

public interface IPortfolioUnitOfWork
{ }

并更改您的 PortfolioUnitOfWork<T>实现:

public class PortfolioUnitOfWork<T> : IPortfolioUnitOfWork where T: class, IPortfolio

现在您可以执行以下操作:

IPortfolioUnitOfWork porfolio = new PortfolioUnitOfWork<Type1>();

ofc,您必须从 PortfolioUnitOfWork<IPortfolio> 更改返回语句和变量类型至 IPortfolioUnitOfWork .

关于c# - 从工厂类返回派生类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21223385/

相关文章:

.net - 在数据库中删除行后更新 DbSet.Local

c# - 等到我的 BackgroundWorker 完成才能打开新的 BackgroundWorker

c# - 创建新线程,传递参数

entity-framework - "update-database" Entity Framework 代码先不加表

Java 接口(interface) Start/Stop 已经存在?

linux - 如何从 Linux 中使用 wsHttpBinding 访问 WCF SOAP 服务?

asp.net-mvc - ASP.NET MVC 4,迁移 - 如何在生产服务器上运行 'update-database'

c# - VBProjectsEvents 在哪里?

c# - 使用 NHibernate 对象模型(不是 tsql)如何确定列定义是否具有标识集?

java - 选择接口(interface)或抽象类