簡體   English   中英

C#泛型對模型集的限制(沒有相關的基類)

[英]C# Generics limit to set of models (without a relating base-class)

無法弄清楚用什么Google可以解決這個問題,但我希望有一種方法可以簡化這一過程。 我有一組正在使用的實體,它們不擴展基類(Level1,Level2等)。 Level1是根,Level2是第二層,並引用Level1等。 我已經大大簡化了下面的示例,但是有很多“重復的”,模板化的代碼,並且正在尋找一種簡化它的方法。

我有一組類似於“組織”的實體,我只關心IDNameParent 我有一個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 ,但是由於相似性,這是有道理的。 如果不是,則可以刪除OrgBOParent屬性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM