[英]C# Generics limit to set of models (without a relating base-class)
無法弄清楚用什么Google可以解決這個問題,但我希望有一種方法可以簡化這一過程。 我有一組正在使用的實體,它們不擴展基類(Level1,Level2等)。 Level1是根,Level2是第二層,並引用Level1等。 我已經大大簡化了下面的示例,但是有很多“重復的”,模板化的代碼,並且正在尋找一種簡化它的方法。
我有一組類似於“組織”的實體,我只關心ID
, Name
和Parent
。 我有一個OrgBO
類,將它們包裝起來,每個實體類型都具有BuildFrom
方法。
//OrgBO class
public void BuildFrom(Level1 entity){
this.ID = entity.Level1ID;
this.Type = OrgTypes.Level1;
this.Name = entity.Name;
this.Parent = null;
}
public void BuildFrom(Level2 entity){
this.ID = entity.Level2ID;
this.Type = OrgTypes.Level2;
this.Name = entity.Name;
this.Parent = new OrgBO(entity.Level1);
}
我為每種類型創建了一個構造函數:
public OrgBO(Client entity){
BuildFrom(entity);
}
public OrgBO(Region entity) {
BuildFrom(entity);
}
但是我重復自己,我失去了一個generic
抽象這種方式? 以某種方式有一個調用BuildFrom<T>
構造函數,並以某種方式將其約束到類類型列表中?
//not sure how to limit to my types..
public OrgBO<T>(T entity) {
BuildFrom<T>(entity);
}
希望這不是一個清晨的屁。額外信息(以防偷窺)。
public enum OrgTypes {
Level1 = 1,
Level2 = 2,
Level3 = 3,
Level4 = 4
};
這是我如何實現的...謝謝@IC。 推動我朝正確的方向前進
public OrgBO(IOrgBase entity){
PopulateFrom(entity);
}
public void PopulateFrom(IOrgBase entity){
this.ID = entity.GetID();
this.Type = entity.GetEntityType();
this.Name = entity.GetName();
if (entity.GetParent() !=null)
{
this.Parent = new OrgBO(entity.GetParent());
}
}
---實體框架擴展類...
namespace Unboxed.Models
{
public interface IOrgBase{
string GetName();
int GetID();
IOrgBase GetParent();
string GetEntityType();
}
[MetadataType(typeof(Level1_Meta))]
public partial class Level1 : IOrgBase{
#region IOrgBase impl
public string GetName()
{
return Level1Name;
}
....
#endregion IOrgBase impl
...
}
}
如果您不想讓您的級別類從通用基類繼承,請使其從通用接口繼承
public interface IEntity
{
int ID { get; set; }
OrgTypes Type { get; } // Only getter, classes must know their own type.
string Name { get; set; }
IEntity Parent { get; set; }
}
現在,您可以像這樣聲明Org類型:
public class OrgBO<TEntity, TParent> : IEntity
where TEntity : IEntity // Generic type constraints
where TParent : IEntity
{
private TEntity _entity;
public OrgBO(TEntity entity)
{
_entity = entity;
if (entity.Type == OrgTypes.Level1) {
this.ParentBO = null;
} else {
this.ParentBO = new OrgBO<TParent>(entity.Parent);
}
}
public int ID { get { return _entity.ID; } set{ _entity.ID = value; } }
public OrgTypes Type { get { return _entity.Type; } }
public string Name { get { return _entity.Name; } set{ _entity.Name = value; } }
// Implement explicitly in order to hide it if not accesses through interface.
IEntity IEntity.Parent {
get { return _entity.Parent; }
set{ _entity.Parent = value; }
}
public OrgBO<TParent> ParentBO { get; private set; }
}
一個關卡類可能看起來像這樣:
public class Level2 : IEntity
{
public int ID { get; set; }
public OrgTypes Type { get { return OrgTypes.Level2; } }
public string Name { get; set; }
public IEntity Parent { get; set; }
public Level1 Level1Parent {
get { return (Level1)Parent; }
set { Parent = value; }
}
}
將虛擬TParent
用於Level1對象,例如new OrgBO<Level1, object>(level1Object)
。 當然,如果更適合您的需求,您也可以將實體值復制到OrgBO對象中,而不是包裝實體對象。
同樣, OrgBO
不一定必須實現IEntity
,但是由於相似性,這是有道理的。 如果不是,則可以刪除OrgBO
的Parent
屬性。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.