2

私は実際にすべての共分散の質問を検索しましたが、私の問題のようには見えません。

私はユーザーコントロールを持っています(明らかな理由で、このクラスは一般的ではありません)、そしてそれは次のようになります:

class MyUserControl : UserControl
{
    private BaseDao<object> _dao;
    private AppointmentMapping<object> _mapping;

    // I need these 2 generics to type safe the mapping/dao relation
    public void RegisterPersistence<T>(BaseDao<T> dao, AppointmentMapping<T> mapping)
   {
        // These two dont work. even with safe and unsafe casting.
        _dao = dao;
        _mapping = mapping;
   }
}

私はすでに共分散、インターフェースなどのデリゲートを保存しようとしました。オブジェクトを保存しないだけです!どうすればこれを達成できますか?これはJavaで簡単に実現できます。

4

4 に答える 4

2

これを次のように試してください。アイデアは、使用時にTをキャプチャし、「後で何をすべきかを知っている」クラスに格納することです。次に、インターフェースを介してクラス内のアイテムを参照します(タイプ情報を省略します)。後で、インターフェースを介して保存された値を呼び出します。そうすれば、特定のインターフェースを実装するためにジェネリッククラスをリファクタリングする必要がありません。

class MyUserControl : UserControl
  {

    // hold a reference to the helper - no generics needed here -> "covariant"
    private IHelper helper;

    // I need this 2 generics to type safe the relation between the mapping and the dao
    public void RegisterPersistence<T>(BaseDao<T> dao, AppointmentMapping<T> mapping) {
      // "pass <T>" for later usage
      this.helper = new HelperImpl<T>(dao, mapping);
    }

    // use the stored values...
    public void doStuff() {
      helper.doStuff();
    }

    // the non generic interface
    private interface IHelper
    {
      void doStuff();
    }

    // a generic implementation for storing the items *and* using them.
    private sealed class HelperImpl<T> : IHelper
    {
      private readonly BaseDao<T> dao;
      private readonly AppointmentMapping<T> mapping;

      public HelperImpl(BaseDao<T> dao, AppointmentMapping<T> mapping) {
        this.dao = dao;
        this.mapping = mapping;
      }

      public void doStuff() {
        this.dao.foo();
        this.mapping.foo();
      }
    }
  }
于 2013-02-06T15:11:35.367 に答える
1

共変性と反変性を使用するには、インターフェースが必要です。

共分散:IInterface<out T>

共変性:IInterface<in T>

詳細については、次のリンクを確認してください: http ://weblogs.asp.net/dixin/archive/2009/08/31/understanding-csharp-covariance-and-contravariance-3-samples.aspx

于 2013-02-06T13:41:33.120 に答える
0

これは私の知る限り不可能です。

セバスチャンが言ったように、あなたができることは持っていることです

class MyUserControl : UserControl
{
    private object _dao;
    private object _mapping;

    // I need this 2 generics to type safe the relation between the mapping and the dao
    public void RegisterPersistence<T>(BaseDao<T> dao, AppointmentMapping<T> mapping)
   {
        _dao = dao;
        _mapping = mapping;
   }


   public BaseDao<T> GetDao<T>()
   {
       return _dao as BaseDao<T>;
   }

   public AppointmentMapping<T> GetAppointmentMapping<T>()
   {
       return _mapping as AppointmentMapping<T>;
   }
}
于 2013-02-06T12:32:38.297 に答える
0

H.alexは正しいです。最良の方法は、ジェネリックビットを別のレイヤーに移動して、クラスをジェネリックにしてから、オブジェクトではなくジェネリッククラスメンバーを使用できるようにすることです。クラスはジェネリック型を推測できる必要があります。そうでない場合は、次のように記述する必要があります。

public class BaseDao<T>
{
    public T Item { get; set; }
}

public class TestClass
{
    private BaseDao<object> _dao;

    public void RegisterPersistence<T>(BaseDao<T> dao)
    {
        _dao = Activator.CreateInstance<BaseDao<object>>();
        //need to map each member of BaseDao
        _dao.Item = dao.Item;
    }    
}

新しいインスタンスのすべてのメンバーのマッピングに注意する必要があるため、これは明らかに保守できません。

于 2013-02-06T14:01:36.010 に答える