1

私は次のものを持っています。

public interface IMyService<T>
   where T: BaseModelType
{
    Process(T input);
}        

public class BaseModelType
{
  ...some property
}

public class SomeClass : BaseModelType
{
   ...some properties
}

public ServiceImpl : IMyService<SomeClass>
{
    ...the properties
}

次に、ジェネリックインターフェイスのすべての実装を登録するユニティコンテナがあります。unitycontainerのresolveメソッドを使用してインターフェースを取得し、それに対していくつかの作業を実行できるようにしたいと思います。Resolveメソッドを使用したいときは、実行時にタイプがあります

 new UnityContainer.Resolve(myTypeVar)

どういうわけかこれをキャストできますか

 IMyService<BaseModelType> value = new UnityContainer.Resolve(myTypeVar) //want to cast it here from object.

インターフェイスが定義するProcessメソッドを呼び出すことができるようにします。

4

1 に答える 1

3

いいえ、IMyService<SomeClass>実装していないためIMyService<BaseModelType>です。Process メソッドの実装を見ると、次のようになります。

public void Process(SomeClass input){...}

これは明らかに、あなたがそれを与えていることを前提としていますSomeClass。のメンバーに安全にアクセスできる必要がありSomeClassます。しかしBaseModelType、パラメータとして a を指定してこのメ​​ソッドを呼び出した場合、それは機能しませんよね?

実行時に引数が特定のジェネリックインターフェイスに適した型になることがわかっていると仮定すると、次の 2 つのオプションがあります。inputIMyService<T>

  1. リフレクションを介してジェネリック メソッド シグネチャを呼び出します。少し遅いですが、効果的です。
  2. を受け取る の非汎用親インターフェースを追加しIMyServiceますBaseModelType。サービスの実装では、入力をその実装の予想される型にキャストすることで、このメソッドを実装できます。これには、より多くのコードが必要です。ただし、このメソッドを実装する一般的な抽象基本クラスを用意することで、それをいくらか軽減できるため、他の実装では必要ありません。

    void Main()
    {
        var s = (IMyService)new ServiceImpl();
        s.Process(new SomeClass());
    }
    
    public interface IMyService
    {
        void Process(BaseModelType input);
    }
    
    public interface IMyService<in T> : IMyService
       where T: BaseModelType
    {
        void Process(T input);
    }
    
    public class BaseModelType{}
    
    public class SomeClass : BaseModelType{}
    
    public abstract class ServiceBase<T> : IMyService<T>
        where T: BaseModelType
    {
         void IMyService.Process(BaseModelType input)
         {
             Process((T)input);
         }
    
         public abstract void Process(T input);
    }
    
    public class ServiceImpl : ServiceBase<SomeClass>{
        public override void Process(SomeClass input){}
    }
    
于 2012-12-13T15:58:38.617 に答える