TL; DR:重新定义方法的返回类型
是否有某种方式来添加一个抽象方法的基类,可以派生类要覆盖的方法的返回类型,而不使用泛型,并且不使用关键字
new
?
我正在开发LLBLGEN Pro的一些自定义模板。在这个过程中,我拒绝更改LLBLGen Pro提供的默认模板,以便我的方法不会覆盖其他人的文件,如果他们选择实现我的模板。
我开始研究的一个任务是开发一个为每个实体生成DTO的模板。沿着这些路线,一个目标是为我的实体提供ToDTO()
方法。为了泛型编程的兴趣,我决定在一个通用的基类中定义这个方法,这就是我的麻烦开始的地方。
请记住,在基类中定义的ToDTO()
方法的目的是因为我希望创建一个通用存储库(与Fetch()
方法,例如),我想有解决CommonEntityBase
,而不是一个特定的实体。
LLBLGEN定义其CommonEntityBase
类,像这样:
public abstract partial class CommonEntityBase : EntityBase2 {
// LLBLGen-generated code
}
我原来的计划是我的方法添加到另一个部分类,像这样:
public abstract partial class CommonEntityBase {
public abstract CommonDTOBase ToDto();
}
我认为继承类将能够在其方法中将返回类型定义为从基类的返回类型派生的类型,如下所示:
public partial class PersonEntity : CommonEntityBase {
public override PersonDTO ToDto(){ return new PersonDTO(); }
}
但是I was wrong。
我的第二次尝试使用泛型定义类,因为这样的:
public abstract partial class CommonEntityBase<T> : CommonEntityBase
where T : CommonDTOBase {
public abstract T ToDto();
}
够简单。我所要做的就是让我生成的实体类从这个新的实体库继承。只是一个警告。因为我不想覆盖LLBLGen的模板,所以它回到了部分类。
LLBLGEN的个别实体有这样的定义:
public partial class PersonEntity : CommonEntityBase {
// LLBLGen-generated code
}
而且这里存在我的问题。为了让我的方法来工作,我会创造我自己的部分类这样的定义:
public partial class PersonEntity : CommonEntityBase<PersonDTO> {
public override PersonDTO ToDto(){ return new PersonDTO(); }
}
当然,这是不可能的,因为,as I now know,
所有的指定基类的[部分类]部分必须同意,但省略基类的部分仍继承基类型。
我要去尝试简单地重写基类的函数定义与new关键字第三件事:
public abstract partial class CommonEntityBase {
public virtual CommonDTOBase ToDto(){ return null; }
}
public partial class PersonEntity : CommonEntityBase {
public new PersonDTO ToDto(){ return new PersonDTO(); }
}
然而,这完全违背了我的做法的目的,因为我希望能够访问PersonEntity
的ToDTO()
方法,当它投射为CommonEntityBase
时。通过这种方法,这样做的:
CommonEntityBase e = new PersonEntity();
var dto = e.ToDto();
会导致dto
是空的,我不想要的。
我遇到variouslinks讨论我的第一种方法,为什么它不会工作,通常指着我的通用方法是在一般意义上的解决方案。但是,在我的情况下,仿制药似乎不起作用。
所有这些问是否我想要完成的是可能的。
是否有某种方法可以将抽象方法添加到允许派生类重写方法的返回类型而不使用泛型且不使用关键字new
?
或者我可能从错误的角度来解决这个问题,还有其他技术可以解决我的问题吗?
编辑
这里有一个用例为想什么,我与实体来完成,以Porges's方法:
public class BaseRepository<D,E> where D : CommonDTOBase where E : CommonEntityBase,new
public D Get(Guid id){
var entity = new E();
entity.SetId(id);
// LLBLGen adapter method; populates the entity with results from the database
FetchEntity(entity);
// Fails, as entity.ToDto() returns CommonDTOBase, not derived type D
return entity.ToDto();
}
}
你似乎有一些'partial'类的概念问题。没有魔法参与;我认为最好的方法是编译器在编译之前将所有为分部类定义的代码填充到一个类定义中。 – porges 2010-06-27 03:35:56
Google“协变返回类型”。 – 2010-06-27 13:06:00