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