2016-08-08 51 views
0

常规接口:Decorator模式和泛型

public interface IComputation 
{ 
    void Reset(); 
    float GetValue1(); 
    float GetValue2(); 
} 

通用接口:

public interface IComputation<T> : IComputation where T : IComputation 
{ 
    T Proxy { get; set; } 
} 

现在的类:

public abstract class Computation<T> : IComputation<T> where T : IComputation 
{ 
    public T Proxy { get; set; }  
} 

班 'ComputationCache' 是“装饰”的计算:

internal abstract class ComputationCache<T> : IComputation where T : IComputation 
{ 
    public T Proxy { get; set; }  

    public float GetValue1() 
    { 
     bool isCached = //check cache. 
     if(!isCached) 
     { 
      //compute value 
      float value1 = Proxy.GetValue1();       

      //update cache 

      return value; 
     }  
    } 
} 

要初始化装饰计算,我试过如下:

public ComputationCache(IComputation<T> proxy) 
{ 
    Proxy = (T) proxy; 
    proxy.Proxy = this; 
} 

...它提供了以下错误“:

Cannot convert source type 'ComputationCache' to target type 'T'.

可以在它是否是更好有人评论使用方法:

ComputationCache<T> : IComputation where T : IComputation 

VS

ComputationCache<T> : IComputation<T> where T : IComputation 
+8

你的抽象看起来有点过分 – Rahul

+1

我必须说,你失去了我 –

+0

@Rahul。上面显示的类是抽象的,并且被多个Computation的子类进行分类,以及从基类缓存类派生的相应的“ComputationCache”。我试图避免在下层重复投射'Proxy'属性 – alhazen

回答

0

首先,你应该使用:

ComputationCache<T> : IComputation<T> where T : IComputation 

如果你想使用缓存为IComputation<T>,并已获得其Proxy财产。

其次,对于您的错误:

Cannot convert source type 'ComputationCache' to target type 'T'.

只是这样做:

proxy.Proxy = (T)(IComputation)this; 

(我不知道为什么会出现这种错误。由于ComputationCache是​​IComputation,像T.。 ..)


编辑:嗯我发现一样东西让我的解决方案错误:

new ComputationCache<Computation<IComputation>>(new Computation<Computation<IComputation>>()); 

这篇文章帮助找到这个错误有关Generics variance

T变得Computation<IComputation>,是不是等于ComputationCache类型。

您可能会遇到一些麻烦,使您在编写Proxy属性时发挥作用。

你可能想要做这样的事情,那么:

public interface IComputation 
{ 
    IComputation Proxy { get; set; } 
    // Other stuff 
} 

public interface IComputation<T> : IComputation where T : IComputation 
{ 
    new T Proxy { get; set; } 
    // Other stuff 
} 

但你必须管理两个属性Proxy

我不知道你在努力达成什么,但这是一个开始。