我正在创建一个游戏以学习C#编程。
我有一个名为Unit
的班级和两个派生类型,Wolf
和Spider
。
我还创建了一个名为UnitList
的类,其中包含List<Unit>
我要存储Unit
个实例的位置。
还有另一个名为Battle
的类,其中一个方法循环遍历Unit
中的每个List<Unit>
。我想基于Type
的{{1}}使用不同的方法,无论是Unit
还是Wolf
。
请参阅下图,因为我不擅长解释概念;我已经坚持了几天。
答案 0 :(得分:1)
您可能正在寻找的是c#is
运营商。
例如
if(unit is Wolf)
{
// Do something
}
else if (unit is Spider)
{
// Do Something
}
进入这些区块后,您可以使用类型转换来调用方法。
if(unit is Wolf)
{
((Wolf)unit).WolfAttack();
}
但是,使用您已经设置的继承树,在C#中有一种更清晰的方法。
class Unit
{
public virtual void Attack()
{
Console.WriteLine("Unit attacks!");
}
}
class Wolf : Unit
{
public override void Attack()
{
Console.WriteLine("Wolf attacks!");
}
}
class Spider : Unit
{
public override void Attack()
{
Console.WriteLine("Spider attacks!");
}
}
通过将Unit
上的方法标记为virtual
,您可以覆盖从Unit
继承的类的行为。因此,现在调用攻击的代码就变成了
foreach(Unit unit in team1.GetList())
{
unit.Attack();
}
因为它会为每个Attack()
调用正确的Unit
函数,无论是Spider
还是Wolf
。
还有一个替代方案,那就是使用Interfaces。如果Spider
和Wolf
类之间没有共享实现,这通常是一种很好的方法,而不是使用abstract
类。
您可以定义IUnit
接口,例如
public IUnit
{
int Health { get; set; }
void Attack();
}
然后,不是继承Unit
,而是实施IUnit
。
class Wolf : IUnit
{
public int Health { get; set; }
public void Attack()
{
Console.WriteLine("Wolf attacks!");
}
}
class Spider : IUnit
{
public int Health { get; set; }
public void Attack()
{
Console.WriteLine("Spider attacks!");
}
}
然后,您可以使用IUnit
代替Unit
。
这两种方法都是有效的,都有优点和缺点。允许类实现许多接口,但只继承一个类。接口无法定义功能,因此无法完全替换继承。还有更多,但这是两者之间最基本的区别。
答案 1 :(得分:1)
您正在尝试将System.Type
与instance
进行比较。您要做的是使用typeof
运算符或is/as
构造用于C#。相反,为了获得更好的解决方案,您可以使用继承。
您可以将Unit类声明为抽象:
abstract class Unit
{
private int health;
private int damage;
protected Unit()
{
health = 100;
}
public abstract void Attack();
}
虽然你的狼课可能是:
class Wolf : Unit
{
public override void Attack()
{
// Do Something...
}
}
然后,您可以从列表中检索每个Unit
个实例并致电Unit.Attack();
,然后调用相应的Attack()
。