与泛型接口中的继承

时间:2020-07-07 09:37:26

标签: c# .net

我正在尝试迁移必须从各种XML读取的应用程序,在将它们持久化到db中之前,每个应用程序都有不同的模型和方法/方法。 因此,我决定为每个实体(XML)创建一个接口IEntityController<T> where T : PersistentEntity和一个实现该接口的控制器,这样它们就可以具有不同的实现...

    public interface IEntityController<T> where T : PersistentEntity
{
    /// <summary>
    /// Check if the data inserted into the xml is valid and all the requirements are met
    /// </summary>
    /// <exception cref="FooValidationException">When the instance is not valid and can't be saved</exception>
    void Validate(T entity);

    /// <summary>
    /// Implement changes in data before its saved
    /// </summary>
    void PreProcess(T entity);

    /// <summary>
    /// Save or Update the entity
    /// </summary>
    /// <exception cref="System.Data.SqlClient.SqlException"></exception>
    void Persist(T entity);

    /// <summary>
    /// Implement changes in data after the entity is saved
    /// </summary>
    void PostProcess(T entity);
}

在那之后,我有一个工厂方法,该方法基于xml返回正确的控制器:

        private IEntityController<PersistentEntity> GetController(XmlFile file)
    {
        Type fileType = file.GetType();

        if(fileType == typeof(FileBoo))
            return (IEntityController<PersistentEntity>) new BooController(DC);
      ......
    }

我的问题是: BooController实现了IEntityController<Boo>的接口,其中Boo继承了PersistentEntity,当尝试将控制器转换为IEntityController<PersistentEntity>时,我得到了InvalidCastException,将BooController强制转换为IEntityController<Boo>没有问题,就像C#忽略了泛型类型的继承一样。

关于如何解决/更好地实现的任何想法? 谢谢

1 个答案:

答案 0 :(得分:0)

最简单的操作是从IEntityController删除通用类型,使其看起来像这样:

 public interface IEntityController
{
    /// <summary>
    /// Check if the data inserted into the xml is valid and all the requirements are met
    /// </summary>
    /// <exception cref="FooValidationException">When the instance is not valid and can't be saved</exception>
    void Validate(PersistentEntity entity);

    /// <summary>
    /// Implement changes in data before its saved
    /// </summary>
    void PreProcess(PersistentEntity  entity);

    /// <summary>
    /// Save or Update the entity
    /// </summary>
    /// <exception cref="System.Data.SqlClient.SqlException"></exception>
    void Persist(PersistentEntity entity);

    /// <summary>
    /// Implement changes in data after the entity is saved
    /// </summary>
    void PostProcess(PersistentEntity  entity);
}

因为您的方法

private IEntityController<PersistentEntity> GetController(XmlFile file)

总是返回PersistentEntity的IEntityController而不是T的IEntityController,而您根本不需要泛型。

记住:

List<string> doesn't inherit from List<object>

否则可能会发生

public static void DestroyTheWorld(List<object> list) {
    list.add(new object());
}

public static void Main() {
    var list = new List<string>();
    DestroyTheWorld(list); //possible if list<string> inherits from list<object>
    //an object has been added to a list of string
}