1

すべてのDAOクラスが派生するジェネリッククラスがあります。これは以下で定義されています。すべてのエンティティの基本クラスもありますが、それは一般的ではありません。

外部キーの関係を満たすために主キーを取得しようとしているため、メソッドGetIdOrSaveは定義した方法とは異なるタイプになりますSabaAbstractDAO。したがって、この関数は、主キーを取得するか、エンティティを保存してから主キーを取得するために使用されます。鍵。

最後のコードスニペットには、一般的な部分を取り除いた場合の動作に関する解決策があるため、分散を使用することでこれを解決できると思いますが、コンパイルするインターフェイスの記述方法がわかりません。

public abstract class  SabaAbstractDAO<T> :ISabaDAO<T> where T:BaseModel

    {
      ...

    public K GetIdOrSave<K>(K item, Lazy<ISabaDAO<BaseModel>> lazyitemdao) 
    where K : BaseModel
    {
         ...
    }

コンパイルしようとすると、このエラーが発生します。

 Argument 2: cannot convert from 'System.Lazy<ORNL.HRD.LMS.Dao.SabaCourseDAO>' to 'System.Lazy<ORNL.HRD.LMS.Dao.SabaAbstractDAO<ORNL.HRD.LMS.Models.BaseModel>>'

私はそれをこのように呼ぼうとしています:

        GetIdOrSave(input.OfferingTemplate,
            new Lazy<ISabaDAO<BaseModel>>(
                () =>
                {
                    return (ISabaDAO<BaseModel>)new SabaCourseDAO() { Dao = Dao };
                })
        );

定義をこれに変更すると、機能します。

    public K GetIdOrSave<K>(K item, Lazy<SabaCourseDAO> lazyitemdao) where K : BaseModel

    {

それで、分散(必要な場合)とジェネリックを使用してこれをコンパイルするにはどうすればよいですか?それで、とでのみ機能する非常に一般的なメソッドを持つことができBaseModelますAbstractDAO<BaseModel>か?メソッドとおそらく抽象クラス定義を変更するだけでよいと思います。使用法は問題ないはずです。

更新: 非常に役立つ応答で、少し改善された例がありますが、興味深いジレンマがあります:

私はこれを今定義しました、そして私は矛盾するエラーを得るのでここにまたはinT持っていません、もしそうなら私はそれがそうであるに違いないと思います、そしてそれで私はそれを不変にしました、それはVS2010が理解できないように見えるからですそれを出します。outout Tcontravariantly validin Tcovariantly valid

public interface ISabaDAO<T> where T:BaseModel
{
    string retrieveID(T input);
    T SaveData(T input);
}

コンパイルはしましたが、このエラーが発生します。

System.InvalidCastException: Unable to cast object of type 'ORNL.HRD.LMS.Dao.SabaCourseDAO' to type 'ORNL.HRD.LMS.Dao.ISabaDAO`1[ORNL.HRD.LMS.Models.BaseModel]'.

上記の2つのコードスニペットを修正しましたが、ここで期待したように分散が機能しないようです。

私はこれを試しました:

public delegate K GetIdOrSave<out K>(K item, Lazy<ISabaDAO<BaseModel>> lazyitemdao)
where K : BaseModel;

しかし、私はインターフェースと同じ問題を抱えています、それを置くoutと不平を言うので、私inは反対の不満を置きます。

これが合法であれば、これを機能させることができると思います。

public delegate K GetIdOrSave<K>(in K item, out Lazy<ISabaDAO<BaseModel>> lazyitemdao)
where K : BaseModel;
4

1 に答える 1

2

デリゲートとインターフェイスを操作する際の共変性と反変性のC#4.0サポート。 Generic Covariance&Contra-varianceはC#4.0でどのように実装されていますか?

したがって、パラメーターとしてインターフェイスを使用してジェネリックデリゲートLazyを使用できる場合は、次のようにしてみてください。

//covariance then you can save Giraffe as SicilianGiraffe but you cannot save Giraffe as Animal; contr-variance realization is not imposible in your case(just theoreticaly)
public interface ISabaDAO<out T> where T: BaseModel{
  int retrieveID(BaseModel);
  T SaveData(BaseModel);
}
public abstract class  SabaAbstractDAO<T> : ISabaDAO<T>{
  ...
  // in this case Lazy should be covariance delegate too
  // delegate T Lazy<out T>();
  public K GetIdOrSave<K>(K item, Lazy<ISabaDAO<BaseModel>> lazyitemdao) where K : BaseModel
  {
    ...
    return (K)itemdao.SaveData(item);// is not safe
    ...
  }
}
public class Course : BaseModel{}
public class SabaCourseDAO : SabaAbstractDAO<Course>{}

//so you can cast SabaCourseDAO to ISabaDAO<Course> and ISabaDAO<Course> to ISabaDAO<BaseModel>
// then next invoking should be valid
GetIdOrSave(new Course (), new Lazy<ISabaDAO<Course>>(() =>

                {

                    return new SabaCourseDAO() { Dao = Dao };

                })

確認できません。VS2010を持っていません。

于 2010-05-21T09:24:28.583 に答える