【问题标题】:c# inheriting from generic classc# 从泛型类继承
【发布时间】:2016-07-04 19:26:24
【问题描述】:

让我描述一下逻辑,然后是类结构。有对象,所有对象都必须继承自 ConfigurationObjectBase。每个对象都必须归 Manager 所有,并且所有 Manager 都必须从 ConfigurationObjectManagerBase 派生。当创建一个新的对象实例时,其中一个构造函数必须接受 Manager 的实例,并且该 Manager 的实例必须将该对象实例添加到其名为 ChildObjects 的属性中。以下是班级样本。您能否根据上述业务规则帮助纠正以下代码?谢谢。

public class ConfigurationObjectBase<ObjectType>
{
    public ConfigurationObjectBase(ConfigurationObjectManagerBase<ObjectType> ownerManager)
    {
        ownerManager.ChildObjects.Add(this);
    }
}


public class ConfigurationObjectManagerBase<ObjectType>
{
    public ConfigurationObjectManagerBase()
    {
        ChildObjects = new List<ObjectType>();
    }

    public List<ObjectType> ChildObjects { get; set; }
}

public class Catalog : ConfigurationObjectBase<Catalog>
{
    public Catalog(CatalogManager ownerManager) : base(???)
    {

    }
}

public class CatalogManager : ConfigurationObjectManagerBase<CatalogManager>
{
    public CatalogManager() : base()
    {
    }
}

【问题讨论】:

    标签: c# generics inheritance


    【解决方案1】:

    您的代码中有两个问题:

    • CatalogManager 应该继承自 ConfigurationObjectManagerBase&lt;Catalog&gt;,而不是 ConfigurationObjectManagerBase&lt;CatalogManager&gt;
    • ChildObjects 应该是ConfigurationObjectBase&lt;ObjectType&gt; 的列表,而不是ObjectType 的列表(否则你不能添加ConfigurationObjectBase&lt;ObjectType&gt; 到它)

    所以代码应该是这样的:

    public class ConfigurationObjectBase<ObjectType>
    {
        public ConfigurationObjectBase(ConfigurationObjectManagerBase<ObjectType> ownerManager)
        {
            ownerManager.ChildObjects.Add(this);
        }
    }
    
    
    public class ConfigurationObjectManagerBase<ObjectType>
    {
        public ConfigurationObjectManagerBase()
        {
            ChildObjects = new List<ConfigurationObjectBase<ObjectType>>();
        }
    
        public List<ConfigurationObjectBase<ObjectType>> ChildObjects { get; set; }
    }
    
    public class Catalog : ConfigurationObjectBase<Catalog>
    {
        public Catalog(CatalogManager ownerManager) : base(ownerManager)
        {
    
        }
    }
    
    public class CatalogManager : ConfigurationObjectManagerBase<Catalog>
    {
        public CatalogManager()
        {
        }
    }
    

    另外,您不需要调用默认的基类构造函数 (base()),它由编译器隐式完成。

    【讨论】:

    • 谢谢。我选择泛型以避免装箱和拆箱的主要原因。在泛型之前,将 ChildObjects 定义为 List。因此,不同类型的管理器存储了 ConfigurationObjectBases 列表,为了访问特定属性,我必须将该列表强制转换为所需的对象。喜欢:List = CatalogMgr.ChildObjects.Cast().ToList().. 你认为现在性能应该还可以吗?谢谢
    • @Tim,没有更多上下文很难说...但至少您的代码现在应该更加类型安全。
    • (CatalogMgr.ChildObjects.First() as Catalog) - 即使不指定“作为目录”,我该如何避免?如果没有“作为目录”,它会返回 ConfigurationObjectBase。谢谢。
    • @Tim,目前您的ConfigurationObjectBase&lt;ObjectType&gt; 不公开甚至不包含ObjectType;你必须添加它。添加ObjectType 类型的新属性并从构造函数参数初始化它。然后您就可以使用CatalogMgr.ChildObjects.First().Object(当然,用您为属性选择的实际名称替换Object
    • 如果有“ownerManager.ChildObjects.Add(this);”那么在 ConfigurationObjectBase 中添加新属性和 ObjectType 类型的原因是什么?逻辑是每个 Manager 都必须有子对象,并且每个列表都特定于定义 Manager 的 ObjectType 类型。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-01
    • 1970-01-01
    • 2018-09-27
    相关资源
    最近更新 更多