繁体   English   中英

如何告诉泛型类实例有关其泛型拥有的集合?

[英]How do I tell a generic class instance about its generic owning collection?

我有一个抽象类“RiskBaseCollection”,它使用泛型本质上是字典的容器。 存储在此字典中的项目类型必须在构造函数中传递,并且它们必须从名为“RiskBase”的基类继承:

我在字典容器类中有一个方法,它调用数据库查询来填充字典的内容(数据库调用取决于另一个字段中设置的内容,但这对我来说并不重要)。

在填充字典时,对于每个数据库记录,我想查看是否已经创建并存储了类的适当实例:如果已经创建和存储,我将检索它并向其添加其他值。 如果没有,我会创建一个 RiskBase 类的新实例。 我已经用泛型做到了这一点,这样实际上创建了正确类型的 RiskBase。

我正在努力解决的是,我想告诉“RiskBase”类的每个实例“拥有”它的集合。 我尝试了各种方法,但无法让它发挥作用。

这是 Collection 类和整个 RiskBase 类的摘录:

public abstract class RiskBaseCollection<T> where T : RiskBase, new() 
{
    public Dictionary<int, T> Items = new Dictionary<int, T>();

    #region Non-critical stuff
      //Removed - not important to my issue.         
    #endregion

    public void ReadData()
    {
        if (ValidConnectionInfo == false)
        {
            return;
        }

        //Create the connection:
        using (OleDbConnection conn = new OleDbConnection(ReaderConnectionString))
        {
            if (conn != null) conn.Open();
            if (conn.State == System.Data.ConnectionState.Open)
            {
                using (OleDbCommand command = new OleDbCommand(SQL, conn))
                {
                    if (command != null)
                    {
                        using (OleDbDataReader reader = command.ExecuteReader())
                        {
                            if (reader != null && reader.HasRows)
                            {
                                while (reader.Read())
                                {
                                    int RiskID = reader.GetValue<int>("ID");
                                    string Title = reader.GetValue<string>("TITLE");
                                    string Status = reader.GetValue<string>("STATUS");
                                    DateTime RaisedDate = reader.GetValue<DateTime>("RAISED_DATE");
                                    DateTime ExpiryDate = reader.GetValue<DateTime>("EXPIRY_DATE");

                                    //Get the FLOC string for the current record
                                    string FunctionalLocation = reader.GetValue<string>("FUNCTIONAL_LOCATION");

                                    T thisRisk = (Items.ContainsKey(RiskID)) ? (T)Items[RiskID] : new T();
                                    thisRisk.RiskID = RiskID;
                                    thisRisk.Title = Title;
                                    thisRisk.Status = Status;
                                    thisRisk.RaisedDate = RaisedDate;
                                    thisRisk.ExpiryDate = ExpiryDate;
                                    thisRisk.AddFunctionalLocation(FunctionalLocation);
                                    thisRisk.Owner = this;      //<=Error: Cannot implicitly convert type 'CRT.Risks.RiskBaseCollection<T>' to 'CRT.Risks.RiskBaseCollection<CRT.Risks.RiskBase>'  
                                    Items[RiskID] = thisRisk;  
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}





public class RiskBase
{
    public RiskBaseCollection<RiskBase> Owner { get; set; }
    public virtual RiskType RiskType { get; set; }

    public RiskBase() { }
    public RiskBase(RiskBaseCollection<RiskBase> riskBaseCollection, RiskType riskType)
    {
        Owner = riskBaseCollection;
        RiskType = riskType;
    }

    public virtual int RiskID { get; set; }
    public virtual string Title { get; set; }
    public virtual string Status { get; set; }
    public virtual DateTime RaisedDate { get; set; }
    public virtual DateTime ExpiryDate { get; set; }

    public virtual List<string> FunctionalLocations { get; set; } = new List<string>();
    public virtual void AddFunctionalLocation(string functionalLocation)
    {
        if (!FunctionalLocations.Contains(functionalLocation)) FunctionalLocations.Add(functionalLocation);
    }
}

本质上,我正在寻找一种为 RiskBase 类设置“所有者”属性的方法。

使RiskBaseCollection<T>实现协变通用接口,并将RiskBase.Owner属性的类型更改为此接口:

// new interface
interface IRiskBaseCollection<out T>
{
    // interface members
}

public abstract class RiskBaseCollection<T> : IRiskBaseCollection<T> 
    where T : RiskBase, new() 
{
    // ...
    thisRisk.Owner = this;  // this now compiles!
}

public class RiskBase
{
    public IRiskBaseCollection<RiskBase> Owner { get; set; }    // interface reference
    // ...
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM