C# 当字典将抽象类作为值时,如何使用子类方法?
我正在做一个国际象棋游戏,我有一个名为cls_ChessPieces的抽象类,每个国际象棋都有一个类(cls_Pawn,cls_Knight,…) 我创建这个抽象类是因为我想将每一个棋子存储在字典中,棋盘上的位置作为键(字符串) 当我放置断点并检查piece1对象时,我可以看到它的类型(cls_Pawn)。但此类型仅在运行时提供给该对象。这使得无法调用CheckLegalMove()方法 这是我解决这个问题的方法,但我认为这不是正确的方法。每一个棋子类都需要大量的代码来完成,每次我想传递对象时,我都需要再次执行此操作C# 当字典将抽象类作为值时,如何使用子类方法?,c#,dictionary,abstract-class,C#,Dictionary,Abstract Class,我正在做一个国际象棋游戏,我有一个名为cls_ChessPieces的抽象类,每个国际象棋都有一个类(cls_Pawn,cls_Knight,…) 我创建这个抽象类是因为我想将每一个棋子存储在字典中,棋盘上的位置作为键(字符串) 当我放置断点并检查piece1对象时,我可以看到它的类型(cls_Pawn)。但此类型仅在运行时提供给该对象。这使得无法调用CheckLegalMove()方法 这是我解决这个问题的方法,但我认为这不是正确的方法。每一个棋子类都需要大量的代码来完成,每次我想传递对象时,
if (piece1 is cls_Pawn)
{
cls_Pawn pawn= (cls_Pawn)piece1;
pawn.CheckLegalMove();
}
有没有一种简单的方法可以通过调用CheckLegalMove()方法从字典中获取cls_pawn类?我试图得到类型:
Type t = piece1.GetType();
但我不知道是否有可能用这种类型的演员
(t)piece1;
谢谢
编辑:
CheckLegalMove()可能不是一个好例子
public bool Promote()
{
// this is a method only this child class should have
}
我猜每种类型的国际象棋项目都需要检查移动,所以在基类中声明方法:
public abstract class cls_ChessPieces
{
public abstract bool CheckLegalMove();
}
class cls_Pawn : cls_ChessPieces
{
public override bool CheckLegalMove()
{
// this is the method I want to call
}
}
您将能够为从cls\u Pawn
派生的每个类调用CheckLegalMove()
:
bool ok = piece1.CheckLegalMove();
我猜每种类型的国际象棋项目都需要检查移动,所以在基类中声明方法:
public abstract class cls_ChessPieces
{
public abstract bool CheckLegalMove();
}
class cls_Pawn : cls_ChessPieces
{
public override bool CheckLegalMove()
{
// this is the method I want to call
}
}
您将能够为从cls\u Pawn
派生的每个类调用CheckLegalMove()
:
bool ok = piece1.CheckLegalMove();
对于这个答案,我假设您不希望在
cls\u ChessPieces
基类中有一个抽象的CheckLegalMove
方法。如果这不是问题,不要选择这种方法
方法1(不推荐)
您可以使用
var type = piece1.GetType();
然后检查每个反射类型是否通过执行以下操作定义了方法CheckLegalMove()
var type = piece1.GetType();
var checkLegalMoveMethod = type.GetMethod("CheckLegalMove");
if(checkLegalMoveMethod != null)
{
var result = (bool)checkLegalMoveMethod.Invoke(piece1);
}
这是可行的,但前提是CheckLegalMove方法不包含任何参数
方法2(推荐方法)
您还可以做的一件事是引入另一个基类(同样,仅当您不想在cls\u ChessPieces
中直接使用CheckLegalMove方法时才这样做)
,该基类定义如下:
class <SubBaseClassName> : cls_ChessPieces
{
public abstract bool CheckLegalMove();
}
class:cls\u棋子
{
公共摘要bool CheckLegalMove();
}
您的
cls\u典当将继承自
,您可以检查piece1
是否属于
类型,如果它是CheckLegalMove
方法,则在其上调用CheckLegalMove
方法。对于这个答案,我想您不想在cls\u ChessPieces
基础中有一个抽象的CheckLegalMove
方法班级。如果这不是问题,不要选择这种方法
方法1(不推荐)
您可以使用
var type = piece1.GetType();
然后检查每个反射类型是否通过执行以下操作定义了方法CheckLegalMove()
var type = piece1.GetType();
var checkLegalMoveMethod = type.GetMethod("CheckLegalMove");
if(checkLegalMoveMethod != null)
{
var result = (bool)checkLegalMoveMethod.Invoke(piece1);
}
这是可行的,但前提是CheckLegalMove方法不包含任何参数
方法2(推荐方法)
您还可以做的一件事是引入另一个基类(同样,仅当您不想在cls\u ChessPieces
中直接使用CheckLegalMove方法时才这样做)
,该基类定义如下:
class <SubBaseClassName> : cls_ChessPieces
{
public abstract bool CheckLegalMove();
}
class:cls\u棋子
{
公共摘要bool CheckLegalMove();
}
您的cls\u典当将继承自
,您只需检查piece1
是否为
类型,如果为CheckLegalMove
方法即可。CheckLegalMove
对于每一个片段来说都是一个有效的问题,因此它的声明无论如何都应该属于抽象基类。重新编辑:在这种情况下,典型的模式仍然是使用Promote
基类方法,在除pawn实现之外的任何实现上抛出一个NotSupportedException
。@Cee抛出NotSupportedExceptions很少是正确的选择(您基本上是在处理静态类型系统)。对于促销,我可以根据总体选择想出几个更好的选择。一个简单的选择是让它piecpromote()=>这个代码>作为基类中的默认实现,并且只在pawn类中覆盖它,还有其他的可能性。我认为要解决这些问题,必须使用一些模式。例如,访问者模式可以应用于这种情况。重新思考体系结构。CheckLegalMove
对于每一个片段来说都是一个有效的问题,因此它的声明无论如何都应该属于抽象基类。重新编辑:在这种情况下,典型的模式仍然是使用Promote
基类方法,在除pawn实现之外的任何实现上抛出一个NotSupportedException
。@Cee抛出NotSupportedExceptions很少是正确的选择(您基本上是在处理静态类型系统)。对于促销,我可以根据总体选择想出几个更好的选择。一个简单的选择是让它piecpromote()=>这个代码>作为基类中的默认实现,并且只在pawn类中覆盖它,还有其他的可能性。我认为要解决这些问题,必须使用一些模式。例如,Visitor模式可以应用于这种情况,我知道在bass类中创建CheckLegalMove()可能更好。但是,如果我创建一个方法Promote(),允许棋子升级到另一个棋子呢。这个方法应该只属于子类cls_Pawn。@jlepers,是的,我同意Promote()不应该在基类中。但也许它也不应该在当铺上。某种棋盘类应该有它,并替换棋盘上的棋子(移除棋子并创建一个新棋子)@jleppers在这种情况下使用模式匹配,例如如果(棋子1是cls_Pawn Pawn){Pawn.CheckLegalMove()}
,这更为具体