1

ジェネリック (C# / 3.5) を使用してヘルパー メソッドを実装しようとしています。基本クラスは次のようになります。

public class SomeNiceObject : ObjectBase
{
  public string Field1{ get; set; }
}

public class CollectionBase<ObjectBase>()
{
  public bool ReadAllFromDatabase();
}

public class SomeNiceObjectCollection : CollectionBase<SomeNiceObject>
{

}

そして、次のようなジェネリック メソッドを使用してコレクションを取得したいと考えています。

    public class DAL
    {

     public SomeNiceObjectCollection Read()
     {
      return ReadFromDB<SomeNiceObjectCollection>();
     }

     T ReadFromDB<T>() where T : CollectionBase<ObjectBase>, new()
     {
      T col = new T();
      col.ReadAllFromDatabase();
      return col;          
     }
   }

これは構築されません

Error   66  The type 'SomeNiceObjectCollection' cannot be used as type parameter 'T' in the generic type or method 'ReadFromDB<T>'.   There is no implicit reference conversion from 'SomeNiceObjectCollection' to 'CollectionBase<ObjectBase>'.

SomeNiceObjectCollection オブジェクトは CollectionBase、正確には CollectionBase です。では、どうすればこれを機能させることができますか?

4

2 に答える 2

2

C# 3.0 ではこれは不可能ですが、C# と .NET 4.0 で共分散と反分散を使用すると、これが可能になる可能性があります。

考えてみてください。派生オブジェクトを含むコレクションを取得し、それを一時的にベース オブジェクトのコレクションとして処理しようとしています。これが許可されていれば、ベース オブジェクトをリストに挿入できますが、これは派生オブジェクトではありません。

次に例を示します。

List<String> l = new List<String>();
List<Object> o = l;
l.Add(10); // 10 will be boxed to an Object, but it is not a String!
于 2009-09-11T12:34:42.733 に答える
2

C# は、リスト型 (共分散) 間のキャストをサポートしていません。

このパターンをサポートするための最善の策は、ReadAllFromDatabase メソッドのインターフェイスを導入して、ジェネリック コレクションに依存しないようにすることです。

public class SomeNiceObject : ObjectBase
{
  public string Field1{ get; set; }
}

public interface IFromDatabase
{
  bool ReadAllFromDatabase();
}

public class CollectionBase<ObjectBase>() : IFromDatabase
{
  public bool ReadAllFromDatabase();
}

public class SomeNiceObjectCollection : CollectionBase<SomeNiceObject>
{

}

public class DAL
{

 public SomeNiceObjectCollection Read()
 {
  return ReadFromDB<SomeNiceObjectCollection>();
 }

 T ReadFromDB<T>() where T : IFromDatabase, new()
 {
  T col = new T();
  col.ReadAllFromDatabase();
  return col;          
 }
}
于 2009-09-11T12:36:32.553 に答える