C#泛型限制模型集(没有相关的基类)

时间:2013-12-30 12:21:22

标签: c# generics

无法弄清楚谷歌要弄清楚这一点,但我希望有一种方法可以简化这一点。我有一组我正在使用的实体,它们不扩展基类(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 
};

2 个答案:

答案 0 :(得分:0)

以下是我如何解决它...感谢@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

      ...

     }
}

答案 1 :(得分:0)

如果您不想让您的级别类继承自公共基类,请将它们从公共接口继承

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; }
    }
}

对{1}}等Level1对象使用虚拟TParent。当然,如果它更符合您的需要,您也可以将实体值复制到OrgBO对象中而不是包装实体对象。

同样new OrgBO<Level1, object>(level1Object)不一定需要实现OrgBO,但由于相似性,它才有意义。如果没有,则可以删除IEntity中的Parent属性。