C# 泛型 - 模仿 C++模板专业化
我在 C++ 模板上找到了一个很好的链接:
http://www.cplusplus.com/doc /tutorial/templates/
并需要 C# 中的类似内容。我有一个似乎有效的解决方案,但希望其他人就其与上述链接(特别是专业化部分)的关系提出意见。
这是我提出的概念证明:
public abstract class Piece
{
public object Value { get; set; }
}
public class Rook : Piece
{
public void Capture()
{
int i = (int)this.Value;
}
}
public class Pawn : Piece
{
public void CaptureEnPassant()
{
string s = (string)this.Value;
}
}
public class PieceFactory<P, T> where P : Piece, new()
{
P p;
public PieceFactory(T value)
{
p = new P();
p.Value = value;
}
public P GetPiece()
{
return p;
}
}
然后最后调用工厂我这样做:
var piece = new PieceFactory<Pawn, string>("exd6").GetPiece();
piece.CaptureEnPassant();
我看到了不同的解决方案,例如使用扩展方法和其他方式......
只是想看看我的思维方式是否一致好的图案的线条。
非常感谢,
大卫
I've found a nice link on C++ Tenmplates:
http://www.cplusplus.com/doc/tutorial/templates/
and needed something similar in C#. I have a solution that seems to work but wanted opinions of others in how it relates to the above link, specifically the specialization section.
Here is a proof of concept I came up with:
public abstract class Piece
{
public object Value { get; set; }
}
public class Rook : Piece
{
public void Capture()
{
int i = (int)this.Value;
}
}
public class Pawn : Piece
{
public void CaptureEnPassant()
{
string s = (string)this.Value;
}
}
public class PieceFactory<P, T> where P : Piece, new()
{
P p;
public PieceFactory(T value)
{
p = new P();
p.Value = value;
}
public P GetPiece()
{
return p;
}
}
and then finally to call into the factory I do this:
var piece = new PieceFactory<Pawn, string>("exd6").GetPiece();
piece.CaptureEnPassant();
I've seen different solutions like using extension methods and other ways...
Just wanted to see if my way of thinking is along the lines of good patterns.
THanks so much,
David
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我的观点是,你的草图比必要的更加复杂和混乱。为什么基类有一个“值”,在每个派生类中都有不同的含义和不同的类型?为什么有一个工厂采用的类型参数必须是特定类型参数,如果不是,则程序在运行时崩溃?摆脱所有那些脆弱的、令人困惑的、脆弱的东西。如果 pawn 需要一个字符串,那么在 Pawn 上创建一个接受字符串的公共构造函数,故事结束。这里根本不需要工厂模式。
不要太迷恋这个工具,以至于用它构建实际上没有任何意义的东西。泛型类型非常适合集合类之类的东西。他们不太适合国际象棋领域。
My opinion is that your sketch is far more complex and confusing than necessary. Why does the base class have a "value" that has different meanings and different types in each derived class? Why is there a factory that takes a type parameter that must be of a particular type argument, and if it is not, then the program crashes at runtime? Get rid of all that brittle, confusing, fragile stuff. If a pawn needs a string, then make a public constructor on Pawn that takes a string, end of story. There's no need for the factory pattern at all here.
Don't be so in love with the tool that you build stuff out of it that doesn't actually make any sense. Generic types are great for things like collection classes. They're not a good fit for the chess domain.
仅供参考,为了好玩,我尝试将自己的模板编程国际象棋引擎转换为 C#,结果发现它的速度大约慢了 20 倍。全面 [原文如此]。
这包括解析游戏文件格式之类的内容。位置查找和移动生成在 C++ 版本中有很多机械同情,应用所有技巧并不能弥补:
也就是说,使用泛型集合的性能优势是显着的,特别是对于
List
YMMV,但最后我想说
FYI I tried converting my own template-programmed chess engine into C# for fun, and found it was slower by roughly a factor of 20 across the board [sic].
That includes stuff like parsing the gamefile format. Position lookup and move generation just had a lot of mechanical sympathy in the C++ version, that applying all the tricks could not make up for:
That said, the performance benefit from using generic collections is significant, esepcially for, say
List<T> where T : struct
. Note however, the caveats from the link above (especially for thenew
constraint which has rather pathetic performance on MS. NET due to code sharing; it is basically as slow as using reflection to call the constructor, even for value types).YMMV, but in the end I'd say
我只会在你的基类上使用泛型。这会破坏您的代码中的某些内容吗?
我还在您的工厂中放置了一些访问关键字(例如
this
和base
)和一个readonly
修饰符。I would just use generics on your base class. Does this break something in your code?
I have also put some access keywords (like
this
andbase
) and areadonly
modifier in your factory.