C# 它';<;中超类的s可能通过子类;T>;?
我有一个名为GenericDao的类C# 它';<;中超类的s可能通过子类;T>;?,c#,oop,nhibernate,polymorphism,C#,Oop,Nhibernate,Polymorphism,我有一个名为GenericDao的类 internal class GenericDao<T> : IGenericDao<T> { } 我有一个问题: public class EmpresaDao { private GenericDao<Empresa> parent { get; set; } public EmpresaDao() { this.parent = new GenericDao<Empresa
internal class GenericDao<T> : IGenericDao<T> {
}
我有一个问题:
public class EmpresaDao {
private GenericDao<Empresa> parent { get; set; }
public EmpresaDao() {
this.parent = new GenericDao<Empresa>();
}
}
公共类EmpresaDao{
私有GenericDao父级{get;set;}
公共行政区(){
this.parent=new GenericDao();
}
}
如何使用子类Assessoria实例化GenericDao?我这样做,但不是工作:
public class EmpresaDao {
private GenericDao<Empresa> parent { get; set; }
public EmpresaDao(Type type) {
if (type == typeof(Assessoria)) {
this.parent = new GenericDao<Assessoria>();
} else {
this.parent = new GenericDao<Empresa>();
}
}
}
公共类EmpresaDao{
私有GenericDao父级{get;set;}
公共EmpresaDao(类型){
如果(类型==类型(评估)){
this.parent=new GenericDao();
}否则{
this.parent=new GenericDao();
}
}
}
简而言之,你真的不能。但是,如果使用非泛型的基本接口,或者使用C#4并使用泛型的基本接口,但带有协变或逆变(取决于需要)类型参数,则可能会有一些欺骗。对于第一种情况:
interface IGenericDaoBase {
}
interface IGenericDao<T> : IGenericDaoBase {
}
public class EmpresaDao {
private IGenericDaoBase parent { get; set; }
public EmpresaDao(Type type) {
// same as before
}
}
接口IGenericDaoBase{
}
接口IGenericDao:IGenericDaoBase{
}
公共类EmpresaDao{
私有IGenericDaoBase父项{get;set;}
公共EmpresaDao(类型){
//和以前一样
}
}
诚然,重新思考您的设计可能会更好。也许EmpresaDao可以采用通用参数本身,其使用方式如下:
public class EmpresaDao<T> where T : Empresa {
private GenericDao<T> parent { get; set; }
public EmpresaDao() {
this.parent = new GenericDao<T>();
}
}
公共类EmpresaDao其中T:Empresa{
私有GenericDao父级{get;set;}
公共行政区(){
this.parent=new GenericDao();
}
}
编辑:事实上,我想得越多,就越相信后一种解决方案是可行的。构造函数中的类型参数正在执行与类签名上的类型参数相同的角色。因此,您不必对调用代码进行太多更改,只需传入一个泛型参数而不是类型对象。您的尝试不起作用是一件好事,如果它起作用,您将引入一个bug 假设我的变量
a
,b
都是EmpresaDao
类型<代码>a由Empresa
父项初始化,而b
由Assessoria
父项初始化。由于a
和b
属于同一类型,因此应该可以在任何地方使用其中一个来代替另一个。假设Assessoria
而不是Empresa
有一个方法assessment()
。但是您希望b.parent
成为Assessoria
,因此您希望调用b.parent.assessment()
,但您不能调用a.parent.assessment()
,这意味着a
和b
首先不应该属于同一类型
解决方案取决于您是否调用.parent.assessment()
:
a) 如果您永远不会在EmpresaDao
类中调用.parent.assessment()
,则让父类的编译时类型始终为Empresa
。以下是一个解决方案:
public class EmpresaDao
{
private Empresa parent {get; set; }
public EmpresaDao(Func<Empresa> parentConstructor)
{
this.parent = parentConstructor();
}
}
static main()
{
var withEmpresaParent = new EmpresaDao(() => new Empresa());
var withAssessoriaParent = new EmpresaDao(() => new Assessoria());
..
}
但是,在调用.parent.assessment()
之前,仍然需要对父级进行运行时检查,这意味着您的设计中仍然存在一些错误。但目前还没有足够的信息来决定要做什么。可能.assessment()
方法应该是私有的,不能从外部调用(即Assessoria
应该是Empresa
:子类上的装饰器,但具有相同的接口)可能“Empresa
holdingEmpresaDao
”和“Assessoria
holdingEmpresaDao
”应该是两个不同的类。(可能实现相同的接口)
编辑:现在我意识到,在我的解决方案中,我错误地将父Empresa或Assessoria类型设置为GenericDao或GenericDao。不过,我相信我的主要观点仍然有效
public class EmpresaDao
{
private Empresa parent {get; set; }
public EmpresaDao(Func<Empresa> parentConstructor)
{
this.parent = parentConstructor();
}
}
static main()
{
var withEmpresaParent = new EmpresaDao(() => new Empresa());
var withAssessoriaParent = new EmpresaDao(() => new Assessoria());
..
}
public class EmpresaDao<T> where T : Empresa
{
private T parent {get; set;}
}