Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#泛型限制为一组模型(没有相关的基类)_C#_Generics - Fatal编程技术网

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

C#泛型限制为一组模型(没有相关的基类),c#,generics,C#,Generics,我不知道谷歌该怎么解决这个问题,但我希望有一种方法可以简化这个问题。我使用的一组实体不扩展基类(Level1、Level2等)。Level1是根,Level2是第二层,并且有对Level1的引用,等等。我已经大致简化了下面的示例,但是有很多“重复的”、模板化的代码,我正在寻找一种简化它的方法 我有一组类似“组织”的实体,我只关心ID,Name,和Parent。我有一个OrgBO类来包装它们,每个实体类型有一个BuildFrom方法 //OrgBO class public void BuildF

我不知道谷歌该怎么解决这个问题,但我希望有一种方法可以简化这个问题。我使用的一组实体不扩展基类(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
,并以某种方式将其约束到类类型列表

//not sure how to limit to my types..
public OrgBO<T>(T entity) {
    BuildFrom<T>(entity);
}

这是我如何做到的。。。谢谢@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; }
}
现在您可以这样声明组织类型:

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; }
    }
}
使用虚拟的
t租金
用于像
new OrgBO(Level1对象)
这样的Level1对象。当然,如果实体对象更适合您的需要,您也可以将实体值复制到OrgBO对象中,而不是包装实体对象


另外,
OrgBO
不一定需要实现
IEntity
,但由于相似性,它是有意义的。如果没有,则可以删除
OrgBO
中的
Parent
属性。

可能更适合于:听起来您可能需要一个接口,但老实说,我不知道是什么阻止您创建“Org”基类?我考虑过为OrgBO创建某种类型的接口和抽象impl,然后有一个工厂找到正确的一个,并建立它,但这似乎是一些过度设计…我希望有一个“迁移到聊天”按钮。。。但它们是数据库实体框架模型。。。基本上是硬编码表Level1是根,Level2是Level1的键,等等。)@Ic。您建议编辑我的EF模型并添加基类?我试图通过模型浏览器来实现这一点,但遇到了一些问题。。你有博客/例子吗?
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; }
    }
}