代码之家  ›  专栏  ›  技术社区  ›  Peter Morris

调用通用接口

  •  1
  • Peter Morris  · 技术社区  · 15 年前
    public interface IProcessor<T>
    {
      void Process(T instance);
    }
    
    
    foreach(AbstractType instance in myClass.SomeCollection)
      OnProcess(instance);
    
    public void OnProcess<T>(T instance)
    {
      IProcessor<T> processor = 
        unityContainer.Resolve<IProcessor<T>>();
      processor.Process(instance);
    }
    

    此代码的问题在于 在里面 OnProcess 总是 AbstractType ,而不是要传递的实例的具体类型。我目前看到两种可能性。

    01:创建非常规 IProcessor 并以此为基础 处理器 . 任何实现者都必须实现通用和非通用 Process 方法,通常是类型转换并传递到泛型方法。

    02:使用 Type.MakeGenericType 得到 处理器 ,解决此问题,然后使用反射调用流程方法。

    这两种方法都有点“不干净”。有人能想出一种方法,我可以做到这一点而不必诉诸于这些实践吗?

    谢谢

    皮特

    2 回复  |  直到 15 年前
        1
  •  3
  •   Marc Gravell    15 年前

    2将是性能杀手(必要的动态/关联 援引 尤其是速度慢)

    1是这个问题的一个常见答案,特别是在显式实现中;问题是获取类型…Unity是否允许使用 Type 例如,而不是通过仿制药?如果是这样的话…当然,你可能还得用 MakeGenericType :

    Type intType = typeof(IProcessor<>).MakeGenericType(instanceType);
    IProcessor proc = (IProcessor) IoC.Resolve(intType);
    

    在哪里? instanceType 也许是通过 instance.GetType() . 出于类似的原因,暴露 T 作为一个 类型 IProcessor :

    public interface IProcessor
    {
        void Process(object instance);
        Type InstanceType {get;}
    }
    public interface IProcessor<T> : IProcessor
    {
        void Process(T instance);
    }
    class SomeClass: IProcessor<int>
    {
        public void Process(int instance)
        {
            throw new NotImplementedException();
        }
        Type IProcessor.InstanceType {get {return typeof(int);}}
        void IProcessor.Process(object instance)
        {
            Process((int)instance);
        }
    }
    

    当然,一个(可选)基类可能允许您避免每个实现中的某些问题:

    abstract class SomeBase<T> : IProcessor<T>
    {
        public void Process(T instance)
        {
            OnProcess(instance);
        }
        Type IProcessor.InstanceType {get {return typeof(T);}}
        void IProcessor.Process(object instance)
        {
            Process((T)instance);
        }
        protected abstract void OnProcess(T instance);
    }
    
        2
  •  0
  •   Andy    15 年前

    如果我理解您的问题,您需要调用依赖于两种类型(处理器类型和正在处理的对象)的进程。对吗?如果是这样的话,您可以对这种问题使用多方法模式。下面是一个例子:

    public interface IProcessor
    {
        void Process( IThingToProcess p ); // Will call p.ProcessMe()
        void Process( ThingToProcess1 concreteP ); // Called back from ThingToProcess1.ProcessMe
    }
    
    public interface IThingToProcess
    {
         void ProcessMe( IProcessor p );
    }
    
    public class ThingToProcess1 : IThingToProcess
    {
        public void ProcessMe( IProcessor p ) { p.Process( this ); }
    }