C# 从传递的类型参数继承成员的泛型抽象类

C# 从传递的类型参数继承成员的泛型抽象类,c#,generics,inheritance,abstract-class,covariance,C#,Generics,Inheritance,Abstract Class,Covariance,我试图找出一种方法来抽象我的适配器逻辑。我希望将从成员继承的泛型抽象类传递给它 public interface IAdaptable<in TIEntity, in TIDTO, TDTO> where TDTO : TIDTO { void Initialize(TIEntity entity); TDTO ToDTO(); } public interface IAdaptable<in TIEntity, TDTO> : IAdaptab

我试图找出一种方法来抽象我的适配器逻辑。我希望将从成员继承的泛型抽象类传递给它

public interface IAdaptable<in TIEntity, in TIDTO, TDTO>
    where TDTO : TIDTO
{
    void Initialize(TIEntity entity);
    TDTO ToDTO();
}

public interface IAdaptable<in TIEntity, TDTO> : IAdaptable<TIEntity, TDTO, TDTO>
{
}

public abstract class AdapterBase<TEntity, TIDTO, TDTO> : IAdaptable<TEntity, TIDTO, TDTO>, TIDTO
    where TDTO : TIDTO
{
    protected TEntity entity;

    public void Initialize(TEntity entity)
    {
         this.entity = entity;
    }

    public TDTO ToDTO()
    {
        return Mapper.Map<TIDTO, TDTO>(this);
    }
} 
公共接口IAdaptable
TDTO的位置:TIDTO
{
作废初始化(第实体);
TDTO ToDTO();
}
公共接口IAdaptable:IAdaptable
{
}
公共抽象类适配器数据库:IAdaptable,TIDTO
TDTO的位置:TIDTO
{
受保护的潜在实体;
公共void初始化(TEntity实体)
{
this.entity=实体;
}
公共TDTO ToDTO()
{
返回Mapper.Map(this);
}
} 
此代码不起作用,因为您无法从传入的泛型参数继承,即使我希望我的父类强制执行它

如果有人想知道为什么或者这里发生了什么,这个适配器库将应用于必须实现DTO接口属性的适配器,然后将附加逻辑应用于getter和设置以防止id篡改,并执行一些基本设置逻辑

如果我手动将此代码应用于每个适配器,则此代码可以正常工作,但我更喜欢适配器库或代理,而不是适配器库,它将为我处理所有这些逻辑


是否有人知道我可以抽象此逻辑的方法,或者解决此问题,这样我就不必手动将此逻辑应用于每个适配器?

对于想要答案的人,我已经找到了解决方案,但您可能不喜欢它

这是完整的界面:

public interface IAdaptable<in TIEntity, in TIDTO, TDTO>
    where TDTO : TIDTO
{
    bool IsInitialized { get;  set; }
    void Initialize(TIEntity entity);
    TDTO ToDTO(TIDTO iEntityDTO);
    void ApplyFrom(TIDTO entityDTO);
}
公共接口IAdaptable
TDTO的位置:TIDTO
{
布尔初始化{get;set;}
作废初始化(第实体);
TDTO ToDTO(TIDTO iEntityDTO);
无效申请自(TIDTO entityDTO)起生效;
}
现在您可以这样创建适配器基座:

public class AdapterBase<TIEntity, TIDTO, TDTO> : IAdaptable<TIEntity, TIDTO, TDTO>
    where TDTO : TIDTO
{
    #region Consts

    public const string FAILED_TO_INITIALIZE_ADAPTER_ERROR = "Failed to Initialize Adapter make sure you called the Initialize function";

    #endregion

    #region Protected Members

    protected TIEntity _entity;

    #endregion

    #region IAdaptable

    public bool IsInitialized { get; set; }

    public void Initialize(TIEntity entity)
    {
        this._entity = entity;
        IsInitialized = true;
    }

    public void ApplyFrom(TIDTO entityDTO)
    {
        if (false == IsInitialized)
        {
            throw new Exception(FAILED_TO_INITIALIZE_ADAPTER_ERROR);
        }

        Mapper.Map(entityDTO, this);

    }

    public TDTO ToDTO(TIDTO adaptable)
    {
        if (false == IsInitialized)
        {
            throw new Exception(FAILED_TO_INITIALIZE_ADAPTER_ERROR);
        }

        return Mapper.Map<TIDTO, TDTO>(adaptable);
    }

    #endregion
}
公共类适配器数据库:IAdaptable
TDTO的位置:TIDTO
{
#区域常数
public const string未能\u初始化\u适配器\u ERROR=“未能初始化适配器确保调用了初始化函数”;
#端区
#区域保护成员
受保护的实体;
#端区
#区域IAdaptable
公共布尔值已初始化{get;set;}
公共无效初始化(TIEntity实体)
{
这个。_实体=实体;
IsInitialized=true;
}
公共作废申请自(TIDTO entityDTO)
{
如果(false==初始值)
{
抛出新异常(未能初始化适配器错误);
}
Map(entityDTO,this);
}
公共TDTO ToDTO(TIDTO自适应)
{
如果(false==初始值)
{
抛出新异常(未能初始化适配器错误);
}
返回Mapper.Map(可调整);
}
#端区
}
现在,您可以在这样的通用crud服务中使用适配器

public class AsyncCRUDService<TEntity, TIDTO, TDTO, TAdapter> : IAsyncCRUDService<TDTO>
    where TDTO : TIDTO
    where TEntity : class, new()
    where TAdapter : class, TIDTO, IAdaptable<TEntity, TIDTO, TDTO>
{
    protected DbContext _context;
    protected TAdapter _adapter;

    public AsyncCRUDService(DbContext context, TAdapter adapter)
    {
        this._context = context;
        this._adapter = adapter;
    }

    public async virtual Task<TDTO> Get(object[] id)
    {
        var entity = await this._context.Set<TEntity>().FindAsync(id);

        if (null == entity)
        {
            throw new InvalidIdException();
        }
        return this.AdaptToDTO(entity);
    }

    protected virtual TDTO AdaptToDTO(TEntity entity)
    {
        this._adapter.Initialize(entity);
        return this._adapter.ToDTO(this._adapter);
    }

}
公共类AsyncCRUDService:IAsyncCRUDService
TDTO的位置:TIDTO
其中tenty:class,new()
其中TAdapter:class、TIDTO、IAdaptable
{
受保护的DbContext\u context;
受保护的适配器;
公共AsyncCRUDService(DbContext上下文,TAdapter适配器)
{
这._context=context;
这个。_适配器=适配器;
}
公共异步虚拟任务Get(对象[]id)
{
var entity=wait this.\u context.Set().FindAsync(id);
if(null==实体)
{
抛出新的InvalidException();
}
返回此.adaptodo(实体);
}
受保护的虚拟TDTO适配器(TEntity实体)
{
此适配器初始化(实体);
返回此.u适配器.ToDTO(此.u适配器);
}
}

唯一的缺点是,现在您的服务与硬依赖相关

我相信castle动态代理是实现这一点的唯一方法,但是我可能错了。@inquisitive谢谢你给我的提示我会调查这些领域你确定这是什么还是一个打字错误:
公共抽象类适配器base:IAdaptable TIDTO
最后一个
TIDTO
@CodingYoshi那是我的错误我最初写的问题没有接口,但是为了更清楚,我把它们放进去了,我现在就更新抱歉,我在遇到问题时删除了原始类我只是从内存中重新创建了这个问题,我删除了一些其他接口方法来解决这个问题