2017-01-11 11 views
1

私は、ジェネリックを本質的に辞書のコンテナとする抽象クラス "RiskBaseCollection"を持っています。この辞書に格納されているアイテムのタイプは、コンストラクタで渡されなければならず、 "RiskBase"という基本クラスから継承しなければなりません。ジェネリッククラスのインスタンスにジェネリック所有コレクションについて教えてください。

コンテンツを取り込むデータベースクエリを呼び出すメソッドが辞書コンテナクラスにあります(データベース呼び出しは別のフィールド内に設定されているものに依存しますが、それは私の要点には重要ではありません)。

データベースレコードごとに、クラスの適切なインスタンスがすでに作成されて保存されているかどうかを確認したい:もしあれば、それを取り出して値を追加します。それがなければ、私はRiskBaseクラスの新しいインスタンスを作成します。私はジェネリックスでこれを行いました。実際に正しいタイプのRiskBaseが実際に作成されています。

私が苦労しているのは、 "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クラスの「所有者」プロパティを設定する手段の後だ:ここで

は、コレクションクラスの抽出物、および全体RiskBaseクラスです。

+0

サイドノート:慎重にコードを掲示上の[MCVE]ガイダンスをお読みください - この記事では、コードの95%は、その質問には関係しません。 –

答えて

1

RiskBaseCollection<T>covariantジェネリックインターフェイスを実装し、このインタフェースに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 
    // ... 
} 
+0

ありがとうございました!よく働く。私は今、この作品が何であるかを理解しようとするために読んで行くでしょう! – ainwood

関連する問題