在.Net語言內,C++/CLI是唯一得天獨厚有兩種泛型的語言,C++/CLI可以用ISO C++既有的template,也可以用CLI的Generics。有了template,C++/CLI也可以實現這個技巧。
69行
template<typename T>
ref class DrawAdapter : public IDrawStrategy, public T {
public:
virtual void draw();
};
80行
int main() {
Grapher^ grapher = gcnew Grapher(gcnew DrawAdapter<Triangle>);
grapher->drawShape();
grapher->setShape(gcnew DrawAdapter<Circle>);
grapher->drawShape();
grapher->setShape(gcnew DrawAdapter<Square>);
grapher->drawShape();
}
C++/CLI也可以在ClIEnt動態改變泛型參數來改善Class Adapter。
看到這裡,你或許會問,C#可以嗎?既然C# 2.0也有泛型,答案很遺憾,目前C# 2.0不行,C# 3.0我還沒試,或許有興趣的朋友可以試看看。
C#
/**//*
(C) OOMusou 2007 http://oomusou.cnblogs.com
Filename : DP_AdpaterPattern_Strategy_ClassByTemplate_Error.cs
Compiler : Visual Studio 2005 / C# 2.0
Description : Demo how to use Strategy Pattern with Adpater Pattern (Class Adapter) By Template
Release : 07/11/2007 1.0
*/
using System;
interface IDrawStrategy {
void draw();
}
class Grapher {
protected IDrawStrategy _drawStrategy;
public Grapher() { }
public Grapher(IDrawStrategy drawStrategy) {
_drawStrategy = drawStrategy;
}
public void drawShape() {
if (_drawStrategy != null)
_drawStrategy.draw();
}
public void setShape(IDrawStrategy drawStrategy) {
_drawStrategy = drawStrategy;
}
}
interface IPaint {
void paint();
}
class Triangle : IPaint {
public void paint() {
Console.WriteLine("Draw Triangle");
}
}
class Circle : IPaint {
public void paint() {
Console.WriteLine("Draw Circle");
}
};
class Square : IPaint {
public void paint() {
Console.WriteLine("Draw Square");
}
}
// Error : Cannot derive from 'T' because it is a type parameter
class DrawAdapter<T> : IDrawStrategy, T {
public void draw() {
paint();
}
}
class ClIEnt {
static void Main() {
Grapher grapher = new Grapher(new DrawAdapter<Triangle>());
grapher.drawShape();
grapher.setShape(new DrawAdapter<Circle>());
grapher.drawShape();
grapher.setShape(new DrawAdapter<Square>());
grapher.drawShape();
}
}
以上C#無法compile成功,錯在55行
// Error : Cannot derive from 'T' because it is a type parameter
class DrawAdapter<T> : IDrawStrategy, T {
public void draw() {
paint();
}
}
錯誤訊息為
Error : Cannot derive from 'T' because it is a type parameter